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