修改打开的文件并保存

时间:2015-07-01 16:21:28

标签: delphi header endianness lzma

我的程序适用于存储在7z / ZIP文件中的一些文件。但是,有些7z / ZIP文件已修改了标题,因此在提取之前必须将它们更改为有效标题。

修改后的标题始终相同,因此它包含在const变量中(以及有效的变量):

for i := 0 to filesize(F) do
begin
  if i < filesize(F) - 3 then
  BlockRead(F, buf, 4);
  if buf = to_fix then
  begin
    Seek(F, i);
    BlockWrite(F, PKZip, 4);
  end;
  buf := 0;
  Seek(F, i+1);
end;

替换解决方案非常简单,我希望我能以正确的方式完成:

to_fix

我得到的问题是,无论何时以小端或大端顺序将PKZip的所有实例替换为04 03 4b 50,我总是会将相同的顺序写入文件:{{1而不是50 4b 03 04

我尝试了以下内容:

const PKZip_B1: array[0..3] of byte = (4,3,75,80);
const PKZip_B2: array[0..3] of byte = (80,75,3,4);

const PKZip_I1 = 67324752;   //04 03 4b 50   to decimal
const PKZip_I2 = 1347093252; //50 4b 03 04   to decimal

以上所有变种都以错误的顺序替换。

为什么会这样?我在64位处理器上使用Delphi 7(我打赌问题是由于这个原因)。

1 个答案:

答案 0 :(得分:1)

x86和x64处理器都是小端。那不是你的问题。

假设您正在将1347093252写为32位整数,其十六进制为$504b0304。您的机器是小端,因此字节以相反的顺序写入。

相反,如果您编写$04034b50,则首先将字节写为$50,依此类推。

但是,如果你真的想按特定顺序写出4个字节,那就做吧。例如,不要将$04034b50写为小端32位整数,而是写:

const 
  Header: array [0..3] of Byte = ($50, $4b, $03, $04);

这是最干净的方法。

这里显然有一定程度的混乱。停止将值视为整数,而将它们视为字节数组。这消除了图片中的字节顺序。然后计算出你需要写入的4个字节,将它们放在一个数组中,然后编写它们。

显然,您需要对从文件中读取的数据应用相同的方法。将其读入数组并比较各个字节。或者,将其读入整数并使用CompareMem与数组进行比较。

最后,我没有看到任何证据表明您肯定找到了正确的4个标头字节。也许您正在修改数据,因此破坏了文件。我一点也不清楚你是否正确地诊断出了这个问题。我建议您在实施解决方案之前确保准确诊断。一旦你有了这个诊断,那么你可能会寻找一个避免首先写错标题值的解决方案。从源头攻击问题。