【问题标题】:How to read binary file created by C/Matlab using JAVA如何使用 JAVA 读取 C/Matlab 创建的二进制文件
【发布时间】:2011-12-05 23:55:55
【问题描述】:

我使用以下 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 次循环后终止,但结果不正确。谁能帮帮我。非常感谢!

【问题讨论】:

  • 结果怎么不正确?例如,您的System.out.println(...) 给出的n 的值是多少?
  • 只是初步猜测:可能是字节序问题
  • 我也在考虑@Curd 的思路。如果您已经解决了问题,请随时自行发布答案,因为它可能对其他人非常有用。
  • 您是否在与 Matlab 代码相同的机器上执行 Java 程序?如果不是,那么我也会怀疑@Curd 建议的字节顺序问题。我想我会解释一下,以防你不明白字节序是什么意思。
  • 同意,很可能与字节序有关。 JVM 是 big-endian,而 Intel x86 架构是 little-endian。 C 代码将遵循底层架构的字节序,(我相信)MATLAB 也是如此。您在什么类型的机器上运行 MATLAB?

标签: java c matlab binary


【解决方案1】:

正如我猜测的那样,这是一个字节顺序问题,即 你的二进制文件写成小端整数 (可能是因为您使用的是 Intel 或类似的 CPU)。

然而,Java 代码正在读取大端整数,无论​​它在什么 CPU 上运行。

为了显示问题,以下代码将读取您的数据并将整数显示为字节序转换前后的十六进制数。

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

如果您不想“手动”更改字节顺序,请参阅此问题的答案 问题:
convert little Endian file into big Endian

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2021-07-26
    • 2011-07-25
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    相关资源
    最近更新 更多