Search code examples
javafileioendianness

Implement fread (readInt) in java


I am attempting to convert a program that reads a binary file in C++ to java. The file is in little-endian.

fread(n, sizeof (unsigned), 1, inputFile);

The snippet above of c++ reads 1 integer into the integer variable 'n'.

I am currently using this method to accomplish the same thing:

public static int readInt(RandomAccessFile inputStream) throws IOException {
    int retVal;
    byte[] buffer = new byte[4];
    inputStream.readFully(buffer);
    ByteBuffer wrapped = ByteBuffer.wrap(buffer);
    wrapped.order(ByteOrder.LITTLE_ENDIAN);
    retVal = wrapped.getInt();
    return retVal;
}

but this method sometimes differs in its result to the c++ example. I haven't been able to determine which parts of the file cause this method to fail, but I know it does. For example, when reading one part of the file my readInt method returns 543974774 but the C++ version returns 1.

Is there a better way to read little endian values in Java? Or is there some obvious flaw in my implementation? Any help understanding where I could be going wrong, or how could I could read these values in a more effective way would be very appreciated.

Update: I am using RandomAcccessFile because I frequently require fseek functionality which RandomAccessFile provides in java


Solution

  • 543974774 is, in hex, 206C6576.

    There is no endianness on the planet that turns 206C6576 into '1'. The problem is therefore that you aren't reading what you think you're reading: If the C code is reading 4 bytes (or even a variable, unknown number of bytes) and turns that into '1', then your java code wasn't reading the same bytes - your C code and java code is out of sync: At some point, your C code read, for example, 2 bytes, and your java code read 4 bytes, or vice versa.

    The problem isn't in your readInt method - that does the job properly every time.