Java从二进制结构文件中读取错误的值
我有一个由Delphi记录组成的文件。记录如下:Java从二进制结构文件中读取错误的值,java,file,delphi,structure,endianness,Java,File,Delphi,Structure,Endianness,我有一个由Delphi记录组成的文件。记录如下: TPoint = record X, Y: Double; end; public Point readPoint() throws IOException { double x = Double.longBitsToDouble( Long.reverseBytes( Doub
TPoint = record
X, Y: Double;
end;
public Point readPoint() throws IOException {
double x = Double.longBitsToDouble(
Long.reverseBytes(
Double.doubleToLongBits(in.readDouble()
)
)
);
double y = Double.longBitsToDouble(
Long.reverseBytes(
Double.doubleToLongBits(in.readDouble()
)
)
);
return new Point(x, y);
}
据我所知,Delphi将数据存储为LittleEndian,Java存储为BigEndian,因此read方法如下所示:
TPoint = record
X, Y: Double;
end;
public Point readPoint() throws IOException {
double x = Double.longBitsToDouble(
Long.reverseBytes(
Double.doubleToLongBits(in.readDouble()
)
)
);
double y = Double.longBitsToDouble(
Long.reverseBytes(
Double.doubleToLongBits(in.readDouble()
)
)
);
return new Point(x, y);
}
一切似乎都很好,但有时我会接受损坏的数据。我得到
638 offset: 10256 Point{x=3.143E-319, y=48.47134}
但我们应该得到
638 offset: 10256 Point{x=22.25315, y=48.47134}
当我打开文件并查看偏移量为10256的数据时,我看到:
7F FB 3A 70 CE 40 36 40
在利特林迪安是22.25315。所以我想知道问题出在哪里?Long.reverseBytes()方法有问题吗?或者不可能把双打从LE转换成BE,反之亦然 我怀疑问题可能是因为您将8个字节作为big-endiandouble
读取,而它们不是big-endian-double。由于位在double
中具有特定的含义,这可能会导致问题——例如,Java可能正在规范化NaN值。这有点像用你知道不正确的编码读取文本数据,然后将其转换回字节
如果从long
开始读取该值,则应保留所有位,以便可以反转字节,然后转换为双精度
:
double x = Double.longBitsToDouble(Long.reverseBytes(in.readLong()));
double y = Double.longBitsToDouble(Long.reverseBytes(in.readLong()));
我怀疑问题可能是因为您将8个字节作为big-endiandouble
读取,而它们不是big-endian-double。由于位在double
中具有特定的含义,这可能会导致问题——例如,Java可能正在规范化NaN值。这有点像用你知道不正确的编码读取文本数据,然后将其转换回字节
如果从long
开始读取该值,则应保留所有位,以便可以反转字节,然后转换为双精度
:
double x = Double.longBitsToDouble(Long.reverseBytes(in.readLong()));
double y = Double.longBitsToDouble(Long.reverseBytes(in.readLong()));
我发现了这个错误。而不是
Long.reverseBytes(Double.doubleToLongBits(in.readDouble())
只需阅读以下内容:
Long.reverseBytes(in.readLong())
我发现了这个错误。而不是
Long.reverseBytes(Double.doubleToLongBits(in.readDouble())
只需阅读以下内容:
Long.reverseBytes(in.readLong())
你为什么一开始就在读一本双人读物?当然你最好使用
Long.reverseebytes(in.readLong())
。我不得不同意。如果以错误的顺序读取double,则可能会发生某种规范化,即在使位反转之前更改位。添加此作为答案,考虑到我怀疑这是问题所在…为什么要从读取double开始?当然你最好使用Long.reverseebytes(in.readLong())
。我不得不同意。如果您以错误的顺序读取double,则可能发生了某种规范化,即在您使位反转之前更改位。添加此作为答案,考虑到我怀疑这是问题所在…感谢您的回复。这确实解决了问题。doubleToLongBits明确地将NaN更改为规范表示,它在javadocs中明确声明了这一点:感谢回复。这确实解决了问题。doubleToLongBits明确地将NaN更改为规范表示,在javadocs中明确说明了这一点: