Search code examples
javac#binarybytefileinputstream

Getting wrong bytes from Java compared to C#


So I have some FRX binary files from which I am attempting to get string captions using Java's binary reading methods.

I was capable of doing so, and specifying the region in which to read bytes 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);
        }
    }

Question Update : Attempting to do the same in Java, I have built the following program. Now I have implemented Guava in order to use LittleEndian equivalents, however now my length prints 24, and as a result I only get the first 24 bytes in my output file. Is ReadInt not appropriate for this situation, and function in a different manner than ReadInt32?

import java.io.*;
import com.google.common.io.*;

public class RealJavaByteReader {

    public static void main(String[] args) throws IOException {

        FileInputStream in = null;
        FileOutputStream out = null;

        try {
            in = new FileInputStream("frmResidency.frx");
            LittleEndianDataInputStream din = new LittleEndianDataInputStream(in);
            out = new FileOutputStream("output.txt");

            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();
            }
        }
    }
}

Solution

  • I realized what my mistake was at this point. Now that LittleEndianDataInputStream has been implemented, I can correctly use SkipBytes to set my initial byte position, and will return the string caption as required. Of course I will initially only produce the first 24 bytes, as whatever is in the first 4 bytes of the binary file must hold a length of 24 for some given property in the FRX file. I must set the offset with skipBytes in order to produce anything meaningful, because the lengths of properties in FRX files are stored in groups of 4 bytes and are followed by those bytes containing that property .

    For instance, if I set din.skipBytes(308);, then the 308th to 312th bytes in the FRX file hold the byte-length of the string in the Caption property I require (for instance 140), which is output by readInt. Thus the next 140 bytes will contain my string required, and my for loop will iterate properly.