Как читать двоичный файл, созданный C / Matlab с использованием JAVA - PullRequest
4 голосов
/ 12 октября 2011

Я создал двоичный файл, используя следующий код Matlab:

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

Я могу использовать следующий код C для чтения этого файла:

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;
}
......

Приведенный выше код C может считывать правильные результаты. Однако сейчас я хочу прочитать такой двоичный файл в JAVA. Мой код отображается следующим образом:

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

Он завершается после n + 1 циклов, но результаты неверны. Кто-нибудь может мне помочь. Большое спасибо!

1 Ответ

4 голосов
/ 12 октября 2011

Как я и предполагал, это проблема с порядком байтов, т.е. ваш двоичный файл записан в виде целых чисел с прямым порядком байтов (вероятно, потому что вы используете Intel или аналогичный процессор).

Однако код Java читает целые числа с прямым порядком байтов, независимо от того, на каком процессоре он работает.

Чтобы показать проблему, следующий код прочитает ваши данные и отобразит целые числа в виде шестнадцатеричного числа до и после преобразования порядка байтов.

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

Если вы не хотите изменять порядок байтов вручную, смотрите ответы на этот вопрос. вопрос:
конвертировать маленький файл Endian в большой Endian

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...