Reputation: 3386
I have built a simple Java program to read data from FRX property files. The issue I am having however, is I need to be able to only read a certain part of the binary from the file. More specifically, I need to begin reading from the file at the value corresponding to a given hex value, and end reading where the ASCII characters stop for that given string of text.
I was capable of doing this in C# using the following program :
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
public class GetFromFRX
{
public static void Main()
{
StringBuilder buffer = new StringBuilder();
using (BinaryReader b = new BinaryReader(File.Open("frmResidency.frx", FileMode.Open)))
{
try
{
b.BaseStream.Seek(641, SeekOrigin.Begin);
int length = b.ReadInt32();
for (int i = 0; i < length; i++)
{
buffer.Append(b.ReadChar());
}
}
catch (Exception e)
{
Console.WriteLine( "Error obtaining resource\n" + e.Message);
}
}
Console.WriteLine(buffer);
}
}
And this is my Java program, with which I believe I can just use DataInputStream to do what I need, however I'm unsure of how to use its methods to seek a hex position to start reading bytes and set the length properly. If I run this current code I get no output written in my new text file, where I would expect to just get the output past the first 10 bytes, so I think I don't understand ReadInt()
or skipBytes
correctly:
import java.io.*;
import java.util.*;
public class Tester3 {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
DataInputStream din = null;
DataOutputStream dout = null;
try {
in = new FileInputStream("frmResidency.frx");
din = new DataInputStream(in);
out = new FileOutputStream("disisworkinlikeacharm.txt");
dout = new DataOutputStream(out);
din.skipBytes(10);
int length = din.readInt();
int c;
for(c = 0 ; c < length; c++){
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
if (dout != null) {
dout.close();
}
if (din != null) {
din.close();
}
}
}
}
My question is, is there an easy way to implement seeking a certain hex position and reading binary to a length in my code, or should I be using something like RandomAccessFile to accomplish this...
Upvotes: 0
Views: 1796
Reputation: 490
Well I see one issue: you are writing the index variable of the for loop instead of the next byte from the file. You should at the very least switch out.write(c) to out.write(din.). Do you expect to write the next ten integers or the next 10 bytes? Assuming you want to write the next ten bytes, the following works for me:
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("c:\\tmp\\test.txt");
DataInputStream din = new DataInputStream(in);
out = new FileOutputStream("c:\\tmp\\test.out");
DataOutputStream dout = new DataOutputStream(out);
din.skipBytes(10);
int length = din.readInt();
System.out.println(length);
int c;
for (c = 0; c < length; c++) {
// TODO: first read byte and check for EOF
out.write(din.read());
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
If you can use Java 7, it is a lot less code to use a try-with-resources loop. This code was for Java 6. I am only closing the File input/output streams since they should be the ones maintaining the file handles. You could close the other streams to be on the safe side of course.
Upvotes: 1
Reputation: 2689
Use din.skipBytes(pos) to move to the required offset in your input.
Upvotes: 0