Recent

Author Topic: [SOLVED] How to output the content of TFileStream.ReadBuffer to the user?  (Read 8582 times)

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Hi

I have a program that goes through a directory and finds files. When it finds certain ones, I need it to read the first 65 bytes of their header and then "do stuff" with the values found in the header.

I've learnt in IRC from Laksen that file streams are the way to do this and he kindly got me on the right track so that my app does read in the header of a file :

Code: [Select]
procedure TForm1.ProbeFile(FileIterator: TFileIterator);

type
 TMyHeader = packed record      
 SomeBytes,
 SomeMoreBytes,
 NextBytes: byte;
 end;            

var
  FileToProbe: TStream;
  header: TMyHeader;      

  // Now open the file and read the header
  FileToProbe := TFileStream.Create(FileIterator.FileName, fmOpenRead);
  FileToProbe.ReadBuffer(header, SizeOf(header));
  // Now show the user the content of the header, once you get it working!!!
  FileToProbe.Free;                                                              


So how do I "convert" what FileToProbe.ReadBuffer(header, SizeOf(header)); has done into something I can display in a memo box or something? I am struggling understanding what I actually have in memory at this stage.

Thanks

Ted
« Last Edit: April 13, 2011, 11:40:58 pm by tedsmith »

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: How to output the content of TFileStream.ReadBuffer to the user?
« Reply #1 on: April 09, 2011, 03:29:15 am »
You could simply:
]
Code: [Select]
  Memo1.Lines.BeginUpdate;
  Memo1.Lines.LoadFromFile(FileIterator.Filename);
  while Memo1.Lines.Count > 5 do
    Memo1.Lines.Delete(Memo1.lines.Count - 1);
  Memo1.Lines.EndUpdate; 

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: How to output the content of TFileStream.ReadBuffer to the user?
« Reply #2 on: April 11, 2011, 12:40:18 am »
Hi Typo

That's a neat trick and one that I didn't know about.

Though it does work for most text files or files containing ASCII chars, my app is being used to look at encrypted files that sit encrypted at a lower filesystem level and decrypted at a higher filesystem level. Consequently (I think) when my app is tested on such files, the Memo box shows nothing in the same way as when it's asked to look at graphics files or something that doesn't contain text that can be outputted to a text box. So I assume it can't read the data from such files in this way.

Basically, I need to be able to look at the raw hex of a file, irrespective of it's file content. Do you have any other ideas?
« Last Edit: April 11, 2011, 12:45:30 am by tedsmith »

circular

  • Hero Member
  • *****
  • Posts: 4471
    • Personal webpage
Re: How to output the content of TFileStream.ReadBuffer to the user?
« Reply #3 on: April 11, 2011, 01:01:19 am »
You could do something like this to show hex values :
Code: [Select]
  function dumpHex(var data; count: integer): string;
  var
    p: pbyte;
    i: integer;
  begin
    result := '';
    p := pbyte(@data);
    for i := 1 to count do
    begin
      if i <> 1 then result += ' ';
      result += intToHex(p^, 2);
      inc(p);
    end;
  end;

...

begin
  ...
  Memo1.Text := dumpHex(header, sizeof(header));
end;
Conscience is the debugger of the mind

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: How to output the content of TFileStream.ReadBuffer to the user?
« Reply #4 on: April 13, 2011, 11:16:04 pm »
I did it in the end after a tip from Laksen in the IRC channel. Posted here for other users who may be seeking to do the same. I must say it struck me as surprisingly difficult based on my experience so far of FP - I was expecting this to be easier, given how many times people must need to do it. Anyway, thanks to all that helped me.

Code: Pascal  [Select][+][-]
  1. // Created a Packed Record array
  2.  
  3. type
  4.  TMyHeader = packed record                
  5.      OriginalFileSize: array[0..7] of byte;
  6.      SpecialMarker: array [0..7] of byte;  
  7.      // and so on....
  8.  
  9. FileToProbe := TFileStream.Create(FileIterator.FileName, fmOpenRead);    
  10.  try
  11.     FileToProbe.seek(0, soFromBeginning);
  12.     FileToProbe.ReadBuffer(header, SizeOf(header));
  13.     edit1.text:= '';
  14.  
  15.     for i:= 0 to 7 do
  16.       edit1.text:= edit1.text + IntToHex(header.OriginalFileSize[i], 2);
  17.  
  18.     for i:= 0 to 7 do
  19.       edit1.text:= edit1.text + IntToHex(header.SpecialMarker[i], 2);
  20.  
  21.      // and so on....
  22.  
  23.   finally
  24.     FileToProbe.Free;
  25.   end;                                  
  26.  

« Last Edit: April 13, 2011, 11:53:28 pm by tedsmith »

fabienwang

  • Sr. Member
  • ****
  • Posts: 449
  • Lazarus is the best
    • My blog
Re: How to output the content of TFileStream.ReadBuffer to the user?
« Reply #5 on: April 13, 2011, 11:19:57 pm »
Great tedsmith.
Please add [SOLVED] as prefix on the main topic title :) (edit your first post)

By the way, here is a better algorithm:
Code: Pascal  [Select][+][-]
  1. var
  2.   part1, part2: string;
  3. begin
  4. try
  5.     FileToProbe.seek(0, soFromBeginning);
  6.     FileToProbe.ReadBuffer(header, SizeOf(header));
  7.     edit1.text:= '';
  8.  
  9.     for i:= 0 to 7 do
  10.       part1:= part1 + IntToHex(header.OriginalFileSize[i], 2);
  11.       part2:= part2 + IntToHex(header.SpecialMarker[i], 2);
  12.       if i <= 3 then
  13.         begin
  14.         part3:= part3 + IntToHex(header.FlagSequence[i], 2);
  15.         part4:= part4 + IntToHex(header.FileHeaderExtentSize[i], 2);
  16.         end;
  17.       if i <= 1 then
  18.         part5:= part5 + IntToHex(header.NoOfHeaderExtents[i], 2);
  19. ...
  20.    //then you concatenate parts:
  21.    edit1.text := part1 + part2 + part3 .......
« Last Edit: April 13, 2011, 11:32:13 pm by FabienWang »
I'm using Arch Linux.
Known for: CPickSniff, OpenGrabby
Contributed to: LazPaint

 

TinyPortal © 2005-2018