Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java从二进制结构文件中读取错误的值_Java_File_Delphi_Structure_Endianness - Fatal编程技术网

Java从二进制结构文件中读取错误的值

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

我有一个由Delphi记录组成的文件。记录如下:

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-endian
double
读取,而它们不是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-endian
double
读取,而它们不是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中明确说明了这一点: