4

I have created a binary file using the following matlab code:

x is an array of int32 numbers
n is the length of x

fid = fopen("binary_file.dat", "wb");
fwrite(fid, n, 'int32');
fwrite(fid, x, 'int32');
fclose(fid);

I can use the following C code to read this file:

fp = fopen("binary_file.dat", "rb");
int n;
fread(&n, 4, 1, fp);//read 4 bytes
int *x = new int[n];
for (int i = 0; i < n; i++)
{
int t;
fread(&t,4, 1,fp);//read 4 bytes
x[i] = t;
}
......

The above C code can read correct results. However, I now want to read such binary file in JAVA. My code is shown as follows:

DataInputStream data_in = new DataInputStream(
             new BufferedInputStream(
                    new FileInputStream(
                new File("binary_file.dat"))));
while(true)
{
   try {
      int t = data_in.readInt();//read 4 bytes
      System.out.println(t);
   } catch (EOFException eof) {
    break;
   }
}
data_in.close();

It DOES terminates after n+1 loops, but the results are not correct. Can anybody help me out. Thanks very much!

skyuuka
  • 605
  • 1
  • 6
  • 22
  • 1
    How are the results not correct? What is, for instance, the value of `n` as given by your `System.out.println(...)`? – Gustav Barkefors Oct 12 '11 at 10:18
  • 4
    just a first guess: maybe it's an endianness issue – Curd Oct 12 '11 at 10:39
  • I was thinking along @Curd's lines as well. Feel free to post the answer yourself if you solved it already since it may very well be useful to others. – Gustav Barkefors Oct 12 '11 at 11:03
  • Are you executing the Java program on the same machine as the Matlab code? If not, then I also would suspect the endianness issue as suggested by @Curd. I thought I would explain a bit in case you didn't understand what was meant by endianness. – tdenniston Oct 12 '11 at 13:04
  • Agree, very likely to be endian-related. The JVM is big-endian while the Intel x86 architecture is little-endian. The C code will follow the underlying architecture's endianness, and so (I believe) will MATLAB. What type of machine are you running MATLAB on? – Uffe Oct 12 '11 at 13:50

1 Answers1

4

As I was guessing it is an endianness issue, i.e. your binary file is written as little-endian integers (probably, because you are using a Intel or similar CPU).

The Java code, however, is reading big-endian integers, no matter what CPU it is running on.

To show the problem the following code will read your data and display the integers as hex number before and after endianness conversion.

import java.io.*;

class TestBinaryFileReading {

  static public void main(String[] args) throws IOException {  
    DataInputStream data_in = new DataInputStream(
        new BufferedInputStream(
            new FileInputStream(new File("binary_file.dat"))));
    while(true) {
      try {
        int t = data_in.readInt();//read 4 bytes

        System.out.printf("%08X ",t); 

        // change endianness "manually":
        t = (0x000000ff & (t>>24)) | 
            (0x0000ff00 & (t>> 8)) | 
            (0x00ff0000 & (t<< 8)) | 
            (0xff000000 & (t<<24));
        System.out.printf("%08X",t); 
        System.out.println();
      } 
      catch (java.io.EOFException eof) {
        break;
      }
    } 
    data_in.close();
  }
}

If you don't want to do change endianness "manually", see answers to this question:
convert little Endian file into big Endian

Community
  • 1
  • 1
Curd
  • 12,169
  • 3
  • 35
  • 49