Reading files with many types of data!

Does anyone know how can i open a file in order
to read information that they are of the same type.
i.e: How to open a .bmp file and read the 2-headers
and the 2 tables of data that exist in there (it is supposed
that i have already created the apropriate types of
variables that i need: records for the headers,...)
I tried to do such kind of function in a small app
opening a file as TFileStream but i had problems
(for example: read a string[3] and then an integer , that
are sequencially stored in the file , with a record with
a structure that includes a string[3] and an integer field
failed!! The problem in the use of the record i think!!)

Any good idea? :)

Comments

  • : Does anyone know how can i open a file in order
    : to read information that they are of the same type.
    : i.e: How to open a .bmp file and read the 2-headers
    : and the 2 tables of data that exist in there (it is supposed
    : that i have already created the apropriate types of
    : variables that i need: records for the headers,...)
    : I tried to do such kind of function in a small app
    : opening a file as TFileStream but i had problems
    : (for example: read a string[3] and then an integer , that
    : are sequencially stored in the file , with a record with
    : a structure that includes a string[3] and an integer field
    : failed!! The problem in the use of the record i think!!)
    :
    : Any good idea? :)
    :
    You could use the file variable, BlockRead() and BlockWrite() procedures. It also could be that the record was packed when the file was written and you record isn't packed. It could also be that the integer wasn't a 4-byte integer, but a 2- or 1-byte integer.
  • : : : : Any good idea? :)
    : :
    : You could use the file variable, BlockRead() and BlockWrite() procedures. It also could be that the record was packed when the file was written and you record isn't packed. It could also be that the integer wasn't a 4-byte integer, but a 2- or 1-byte integer.
    :
    I haven't tried BlockRead yet but i am going to!
    Is there any way to know if my data are packed and how??
    :-(


  • : : : : : Any good idea? :)
    : : :
    : : You could use the file variable, BlockRead() and BlockWrite() procedures. It also could be that the record was packed when the file was written and you record isn't packed. It could also be that the integer wasn't a 4-byte integer, but a 2- or 1-byte integer.
    : :
    : I haven't tried BlockRead yet but i am going to!
    : Is there any way to know if my data are packed and how??
    : :-(
    :
    :
    :
    It is very difficult to see if the data is packed or not. For that you need an intricate knowledge of the file format. You could try to use trial-and-error, i.e. read it unpacked then packed. Otherwise you need some documentation or the type declarations.
  • Hi,

    I am working same kind of thing, so i wrote these to procedures. I don't know have safe they are and I am still testing and working on them, so please feel free to improve the code. I have also decided to use Resource headers when i store the info in the file.

    I have three types av data in this file.
    1) A header information
    2) Some form Settings
    3) My text info
    You can extend these types if you like. You can also store pictures and texts and everything you like. If you are working with very large files it might be better to use a FileStream instead of a MemoryStream, but I am not sure.

    Btw, I spent a lot of houres before I could make the thing ith Recource Headers work butI think ResourceHeaders are a good way to solve the problem. I hope these codes are helpful to you :)

    Here is My Save prosedure
    [code]

    procedure SaveFile(FileName: string);
    type
    // Different records used in file
    THeader = record
    FileType: string[16]; // I would like to make this a dynamic
    // string but I don't know how :(
    Color: (Blue, Green, Red, Yellow, White, Custom);
    Index: Integer;
    end;

    TSettings = record
    Left, Top, Width, Height: Integer;
    AlphaBlend: Boolean;
    AlphaBlendValue: Byte;
    end;
    var
    Header: THeader;
    Settings: TSettings;
    Stream: TMemoryStream;
    FixupInfo: Integer;
    begin
    // Store Information in records
    with Header do
    begin
    FileType := 'My File';

    case Edit.Color of
    $00EDC8A8: Color := Blue;
    $00CEFFCE: Color := Green;
    $00D2D2FF: Color := Red;
    $00CCFFFF: Color := Yellow;
    $00FFFFFF: Color := White
    else
    Color := Custom;
    end;

    case Color of
    Blue: Index := 1;
    Green: Index := 2;
    Red: Index := 3;
    Yellow: Index := 4;
    White: Index := 5;
    else
    Index := 0;
    end;
    end;

    with Settings do
    begin
    Left := MainForm.Left;
    Top := MainForm.Top;
    Width := MainForm.Width;
    Height := MainForm.Height;

    if MainForm.FormStyle = fsStayOnTop then
    AlwaysOnTop := True
    else
    AlwaysOnTop := False;

    Minimized := MainForm.Minimized;
    AlphaBlend := MainForm.AlphaBlend;
    AlphaBlendValue := MainForm.AlphaBlendValue;
    end;

    // Create the Stream
    Stream := TMemoryStream.Create;
    with Stream do
    try
    // Must include thes three steps to wirte ResourceHeader
    WriteResourceHeader('Header', FixupInfo);
    WriteBuffer(Header, SizeOf(Header));
    FixupResourceHeader(FixupInfo);

    WriteResourceHeader('Settings', FixupInfo);
    WriteBuffer(Settings, SizeOf(Settings));
    FixupResourceHeader(FixupInfo);

    WriteResourceHeader('Message', FixupInfo);
    Edit.Lines.SaveToStream(Stream); // Edit is a Memmo or Image...
    FixupResourceHeader(FixupInfo);

    Stream.SaveToFile(FileName);
    finally
    Stream.Free;
    end;
    end;

    [/code]


    Here is how I load the info

    [code]

    procedure TMainForm.LoadFile(FileName: string);

    procedure ReadResource(Stream: TStream; var Buffer);
    var
    ImageSize: Integer;
    begin
    with Stream do
    try
    ReadResHeader;
    Position := Position - 4;
    ReadBuffer(ImageSize, SizeOf(Longint));
    ReadBuffer(Buffer, ImageSize);
    except
    raise EReadError.Create('Could not read the bolck nformation');
    end;
    end;

    type
    // Same as SaveFile
    // You could declare these records globally for the convinience
    THeader = record
    FileType: string[16];
    Color: (Blue, Green, Red, Yellow, White, Custom);
    Index: Integer;
    end;

    TSettings = record
    Left, Top, Width, Height: Integer;
    AlphaBlend: Boolean;
    AlphaBlendValue: Byte;
    end;
    var
    Header: THeader;
    Settings: TSettings;
    Stream: TMemoryStream;
    ImageSize: Integer;
    begin
    // Create a FileStream and Open it
    Stream := TMemoryStream.Create;
    Stream.LoadFromFile(FileName);
    Stream.Position := 0;
    with Stream do
    if Size = 0 then
    Exit; // Or what ever you like to hapen. Could be a new file...
    else
    // Open File: Load information from the file
    try
    // Load Header Info
    ReadResHeader;
    Position := Position - 4;
    ReadBuffer(ImageSize, SizeOf(Longint));
    ReadBuffer(Header, ImageSize);

    if (Header.FileType <> 'My File') then
    begin
    ShowMessage('BAD FILE');
    Exit;
    end;

    // Load Settings Info
    ReadResource(Stream, Settings);

    // Apply the info
    MainForm.Left := Settings.Left;
    Mainform.Top := Settings.Top;
    MainForm.Width := Settings.Width;
    MainForm.Height := Settings.Height;
    ChangeColor(Settings.Color); // This is not includede here...


    if Settings.AlwaysOnTop = True then
    MainForm.FormStyle := fsStayOnTop;

    MainForm.AlphaBlend := Settings.AlphaBlend;
    MainForm.AlphaBlendValue := Settings.AlphaBlendValue;

    // Load Message Info
    ReadResHeader;
    Edit.Lines.LoadFromStream(Stream);
    finally
    Edit.Modified := False;
    Stream.Free;
    end;
    end;

    [/code]


    For more information about different commands used in the code please see the delphi code (Thats where I learned how to use them).

    Regards,
    Arash
  • Btw, does anyone know how I can search trought a files different resource headers and list them up or seomething.
  • : Btw, does anyone know how I can search trought a files different resource headers and list them up or seomething.
    :
    If the files have the same extension (or filename), then it is easy. Just use a FindFirst(), FindNext(), and FindClose() to enumerate through the files. Each time a new file is found, you read the header string and store it in the memory.
    If your data files don't have a common extension (or filename), then you need to check if the filesize is at least the length of the header before reading it.
    If your datafiles have different lengths of headers, then you need some kind of recognition function.
  • : Thanks for the guidelines!


Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories