Как читать байтовые заголовки нетипизированных файлов, а затем использовать и отображать эти данные, когда они являются файловыми потоками в Free Pascal и Lazarus

Я пытаюсь изучить Free Pascal с помощью Lazarus, и один из моих любимых проектов включает чтение 64-байтовых заголовков определенного набора нетипизированных файлов, которые не могут быть прочитаны и отображены с использованием текстовых или связанных с ASCII процедур (поэтому не могут быть выведены непосредственно в блоки Memo и т. Д. ).

До сих пор я разработал следующий код, который, как мне кажется, считывает 64 байта заголовка, и я использую TStreams и диалоговое окно «Выбрать каталог» для этого на основе рекомендаций, полученных через Lazarus IRC. Мой вопрос, однако, заключается в том, как на самом деле ИСПОЛЬЗОВАТЬ данные, которые считываются в буфер из заголовка? Например, в заголовках есть последовательности из 8 байтов, затем 16 байтов, затем 2 байта и так далее, над которыми я хочу «поработать», чтобы сгенерировать другой вывод, который в конечном итоге будет преобразован в строку для перехода в мою сетку строк. .

Кое-что из того, что у меня есть до сих пор, основано на том, что я нашел здесь написанном Мейсоном Уилером ближе к концу (http://stackoverflow.com/questions/455790/fast-read-write-from-file-in-delphi), но это показывает только, как читать, но не как использовать. Я также читал это (http://stackoverflow.com/questions/4309739/best-way-to-read-parse-a-untyped-binary-file-in-delphi), но опять же, он показывает вам, как ПРОЧИТАТЬ данные тоже, но не ИСПОЛЬЗУЙТЕ впоследствии данные. Любые указания были получены ранее! Пока что приведенный ниже код просто выводит однозначные целые числа в поле редактирования, в отличие, скажем, от диапазона из 8 шестнадцатеричных значений.

PS - Я новичок в программировании, поэтому будьте осторожны! Ничего особенного.

procedure TForm1.ProbeFile(FileIterator: TFileIterator);

type
 TMyHeader = Array[1..64] of packed record
 First8Bytes,
 Next16Bytes,
 Next2Bytes: byte;
 end;

var

  FI : TFileIterator;                      //File Iterator class
  SG : TStringGrid;
  NumRead : SmallInt;
  FileToProbe: TStream;
  header: TMyHeader;

begin
  FI := TFileIterator.Create;
  SG := TStringGrid.Create(self);


  // Open the file and read the header
  FileToProbe := TFileStream.Create(FileIterator.FileName, fmOpenRead);
  try
    FileToProbe.seek(0, soFromBeginning);
    FileToProbe.ReadBuffer(header, SizeOf(header));
    edit1.text := IntToStr(header[0].First8Bytes);  // Just outputs '0' to the field?  If I try '10' it ooutputs '29' and so on
  finally
    FileToProbe.Free;
  end; 

person Gizmo_the_Great    schedule 11.04.2011    source источник


Ответы (1)


Пожалуйста, простите меня, если я неправильно понял ваш вопрос.

Как я понял есть заголовок размером 64 байта. Первые 8 байтов принадлежат друг другу, затем следующие 16 байтов и, наконец, еще 2 байта.

Мне кажется, что объявление для этого заголовка должно быть:

   TMyHeader = packed record
     First8Bytes: array[0..7] of byte;  
     Next16Bytes: array [0..15] of byte;
     Next2Bytes: array [0..1] of byte;
     // add more if you like
   end;

Этот тип записи имеет размер 8 + 16 + 2 = 26 байт.

Ваш код, который читает заголовок, мне кажется нормальным, поэтому я не буду повторять это.

Следующие 16 байт в заголовке можно получить, например, следующим образом:

edit1.text:= '';
// needs a declaration of a variable "i" as integer
for i:= 0 to 15 do
  edit1.text:= edit1.text + IntToStr(header.next16bytes[i]) + '-';

Измените значение первого байта в части next2bytes вашего заголовка следующим образом (снова в качестве примера):

header.next2bytes[0]:= 123;

Наконец, вы можете записать свои изменения обратно в заголовок файла с помощью метода filetoprobe.writebuffer.

person ToonVo    schedule 11.04.2011
comment
Большое тебе спасибо! Это мне очень помогло. Единственное изменение, которое мне пришлось внести в исходный код, - это использовать IntToHex вместо IntToStr с шириной в два, поскольку мне нужно шестнадцатеричное представление каждого байта, а не целое число. Но да, теперь я получаю полную строку значений вместо одного. Еще раз спасибо - person Gizmo_the_Great; 13.04.2011