gpt4 book ai didi

delphi - 如果 Windows/Delphi/IDE 暗示小端顺序,我如何从大端二进制文件中读取整数?

转载 作者:行者123 更新时间:2023-12-03 16:54:46 24 4
gpt4 key购买 nike

我很困扰。我需要读取二进制文件(Applied Biotechnology aka ABIF 的 .fsa 扩展名、FASTA 文件),但在读取有符号整数时遇到了问题。我按照本手册做所有事情 https://drive.google.com/file/d/1zL-r6eoTzFIeYDwH5L8nux2lIlsRx3CK/view?usp=sharing
因此,例如,让我们看看文件头中的 fDataSize 字段 https://drive.google.com/file/d/1rrL01B_gzgBw28knvFit6hUIA5jcCDry/view?usp=sharing
我知道它应该是 2688(根据手册,它是一个 32 位的有符号整数),即二进制形式的 00000000 00000000 00001010 10000000。
实际上,当我将这 32 位读取为 4 个字节的数组时,我得到 [0, 0, 10, -128],这与二进制形式完全相同。
但是,如果我将其读为整数,则会得到 16809994,即 00000001 00000000 10000000 00001010 位。
正如我从多个论坛了解到的,他们使用 Swap 和 htonl 函数将整数从小端顺序转换为大端顺序。他们还建议对 32 位整数使用 BSWAP EAX 指令。但在这种情况下,它们以一种错误的方式工作,特别是:
Swap,应用于 16809994,返回 16779904 或 00000001 00000000 00001010 10000000,BSWAP 指令将 16809994 转换为 176160769,即 000000001 00000000 010000
正如我们所看到的,内置函数的作用与我需要的不同。 Swap 可能会返回正确的结果,但是由于某种原因,将这些位作为整数读取会更改最左侧的字节。
那么,出了什么问题,我该怎么办?
更新。 1
为了存储标题数据,我使用以下记录:

type
TFasMainHeader = record
fFrmt : array[1..4] of ansiChar;
fVersion : Word;
fDir : array[1..4] of ansiChar;
fNumber : array[1..4] of Byte; //
fElType : Word;
fElSize : Word;
fNumEls : array[1..4] of Byte; //
fDataSize : Integer;
fDataOffset : Integer;
fDO : word;
fDataHandle : array[1..98] of Byte;
end;
然后单击按钮后,我执行以下操作:
aFileStream.Read(fas_main_header, SizeOf(TFasMainHeader));
with fas_main_header do begin
if fFrmt <> 'ABIF' then raise Exception.Create('Not an ABIF file!');
fVersion := Swap(fVersion);
fElType := Swap(fElType);
fElSize := Swap(fElSize);
...
接下来我需要以正确的方式交换Int32变量,但此时fDataSize例如为16809994。 调试时详细查看记录的状态:
enter image description here
这对我来说没有意义,因为 fDataSize 值的二进制表示中不应该有一位(它也会破坏 BSWAP 结果)。
查看文件开头的二进制结构(fDataSize 字节高亮显示):
enter image description here

最佳答案

问题与字节序无关,而是与 Delphi records 有关.
你有

type
TFasMainHeader = record
fFrmt : array[1..4] of ansiChar;
fVersion : Word;
fDir : array[1..4] of ansiChar;
fNumber : array[1..4] of Byte; //
fElType : Word;
fElSize : Word;
fNumEls : array[1..4] of Byte; //
fDataSize : Integer;
fDataOffset : Integer;
fDO : word;
fDataHandle : array[1..98] of Byte;
end;
并且您希望此记录覆盖文件中的字节, fDataSize “在上面” 00 00 0A 80 .
但是 Delphi 编译器会在记录的字段之间添加填充以使它们正确对齐。因此,您的 fDataSize将不会处于正确的偏移量。
要解决此问题,请使用 packed关键词:
type
TFasMainHeader = packed record
fFrmt : array[1..4] of ansiChar;
fVersion : Word;
fDir : array[1..4] of ansiChar;
fNumber : array[1..4] of Byte; //
fElType : Word;
fElSize : Word;
fNumEls : array[1..4] of Byte; //
fDataSize : Integer;
fDataOffset : Integer;
fDO : word;
fDataHandle : array[1..98] of Byte;
end;
然后字段将位于预期位置。
然后——当然——你可以使用任何你喜欢的方法来交换字节顺序。
最好是 BSWAP操作说明。

关于delphi - 如果 Windows/Delphi/IDE 暗示小端顺序,我如何从大端二进制文件中读取整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65005050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com