我使用以下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循环后终止,但结果不正确。任何人都可以帮助我。非常感谢!
答案 0 :(得分:4)
正如我猜测它是一个字节序问题,即 你的二进制文件被写成little-endian整数 (可能是因为您使用的是英特尔或类似的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