Archived

This topic is now archived and is closed to further replies.

Blockwrite error

This topic is 4951 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I''m trying to write a program (in Delphi) which packs x number of files into one file. It works fine with one file, but if I try to pack more than one the result is looking odd. With one file the data looks normal but with more than two it writes data about my program like colors, placement in the file-system and fonts, like so:
0&    z   tV• ìV• ôX• D5• Ü$• Ü$•    è$• è$• ô  bord\Delphi\ResEdit\ResEdit.exe %• %• È  entWidth	Color
clBtnôX• D5• Ü$• Ü$•    è$• è$• ô  bord\Delphi\ResEdit\ResEdit.exe %• %• È  entWidthColorclBtnFaceFon
First a little info about my variables:
  Texture = record
    Data : array of Byte;
    Name : String;
  end;

var
  Textures : array of Texture;
  Offsets : array of DWORD;
My code for loading a file is:
procedure LoadImage;
var
  F : File;
begin
  AssignFile(F, Filename);
  Reset(F, 1);
  SetLength(Textures, Length(Textures) + 1);
  while not EoF(F) do
  begin
    SetLength(Textures[High(Textures)].Data, Length(Textures[High(Textures)].Data) + 1);
    with Textures[High(Textures)] do
    BlockRead(F, Data[High(Data)], 1);
  end;
  Textures[High(Textures)].Name := ExtractFileName(Filename);
  CloseFile(F);
end;
And my code for packing all the files are:
var
  F : File;
  Header : array [0..5] of Byte;
  A : Integer;
  Offset : Integer;
begin
    AssignFile(F, Filename {this I declare in another place});
    Rewrite(F, 1);
    Header[0] := 20;
    Header[1] := 48;
    Header[2] := 38;
    Header[3] := 3;
    Header[4] := LOBYTE(Length(Offsets));
    Header[5] := HIBYTE(Length(Offsets));
    BlockWrite(F, Header, SizeOf(Header));
    Offset := SizeOf(Header) + Length(Offsets) * 4;
    for A := 0 to High(Offsets) do
    begin
      Offsets[A] := Offset;
      BlockWrite(F, Offsets[A], 4);
      Inc(Offset, Length(Textures[A].Data));
    end;
    for A := 0 to High(Textures) do
    BlockWrite(F, Textures[A].Data, Length(Textures[A].Data));
    CloseFile(F);
  end;
Anyone who has experienced the same type of problem, or just happends to know how I can fix it?

Share this post


Link to post
Share on other sites
I did a similar thing in C++, using a DLL. I wrote my own DLL which loads and writes the files. My file format looked like this:

[header]
+- Signature[2 bytes]
+- Version[4 bytes]
+- N files inside file[4 bytes]
+- CRC32 value of Index[4 bytes]

[Index, there are N entries]
+- Filename[127 bytes]
+- Start offset in file[4 bytes]
+- Length of file[4 bytes]
+- CRC32 value[4 bytes]

[Data]


I took the number of files that were in the list, write the number of files into the header, write the header to disk, create the indexes. Cycle through all files, insert their names, size and their offset(Which you can calc. Initial offset = sizeof(header) + (N * sizeof(IndexEntry))).

I then wrote all the data to the files, and calculated the CRC32 during writing. After all the data sections were written, I calculated the CRC32 value of the indexes and rewrote the index and the header(Not in that order ).

That''s how I solved it. Probably not the best practice, but it worked perfectly.

Toolmaker




My site
/* -Earth is 98% full. Please delete anybody you can.*/

Share this post


Link to post
Share on other sites
why not make it more simple?

what you need all these offsets for when you are loading them all anyways?!? i don''t know what i''m talking about.. maybe it''s nearly the same i''m gonna write but anyways.. i would do it this way:

type
texture = record
data: array of byte;
name: string;
size: integer;
end;

texturehdr = record
numtex: integer;
end;

texturebank = record
textures: array of texture;
header: texturehdr;
end;

procedure loadbankfromfile(filename: string; var bank: texturebank);
procedure savebanktofile(filename: string; bank: texturebank);

implementation

procedure savebanktofile(filename: string; bank: texturebank);
var f: file;
i: integer;
begin
assignfile(f, filename);
rewrite(f, 1);

bank.header.numtex := high(bank.textures)+1;
blockwrite(f, bank.header, sizeof(texturehdr));

for i := 0 to high(bank.textures) do
begin
bank.textures.size := high(bank.textures[i].data)+1;
blockwrite(f, bank.textures[i].size, sizeof(integer));
end;

for i := 0 to high(bank.textures) do
begin
blockwrite(f, bank.textures[i].data[0], high(bank.textures[i].data)+1);
end;
end;

procedure loadbankfromfile(filename: string; var bank: texturebank);
var f: file;
i: integer;
begin
assignfile(f, filename);
reset(f, 1);

blockread(f, bank.header, sizeof(texturehdr));
setlength(bank.textures, bank.header.numtex);

for i := 0 to high(bank.textures) do
begin
blockread(f, bank.textures[i].size, sizeof(integer));
setlength(bank.textures[i].data, bank.textures[i].size);
end;

for i := 0 to high(bank.textures) do
begin
blockread(f, bank.textures[i].data[0], high(bank.textures[i].data)+1);
end;
end;

Share this post


Link to post
Share on other sites
quote:
what you need all these offsets for when you are loading them all anyways


How else should I know where and when the files start and end?

Share this post


Link to post
Share on other sites