Изменить открытый файл и сохранить его

Моя программа работает с некоторыми файлами, которые хранятся в файле 7z/ZIP. Однако некоторые из файлов 7z/ZIP имеют измененные заголовки, поэтому перед извлечением необходимо изменить их на допустимые.

Измененные заголовки всегда одинаковы, поэтому они содержатся в переменной const (вместе с допустимой):

to_fix := 1629246124;
PKZip := 1347093252;

Решение по замене довольно простое, и я надеюсь, что я сделал это правильно:

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 вместо 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

Все вышеперечисленные варианты заменяют в неправильном порядке.

Почему это происходит? Я использую Delphi 7 на 64-битном процессоре (держу пари, что проблема связана с этим).

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 байта заголовка. Возможно, вы также изменяете данные и повреждаете файл. Мне совсем не ясно, что вы правильно поставили диагноз. Я предлагаю вам убедиться, что у вас есть точный диагноз, прежде чем внедрять решение. Если у вас есть этот диагноз, то вы можете искать решение, которое в первую очередь позволит избежать неправильного ввода значения заголовка. Атаковать проблему в источнике.

Другие вопросы по тегам