Member Avatar for Thew

Hello,
I want to put some files together, but
I have problem, when I'm trying to write data into opened file from another file.

Structure of compiled file:
- Head: total count of files in file
- Sizes: names and the sizes of the files
- File Streams

so I wrote a script to write head and sizes. It worked fine, but when I tried to add a script to read file from a list and write its content into the compiled file, I detected some errors. This is the code (it's just a part, not everything):

THead = record
  count:byte;
end;

TSizes = record
  size:LongWord;
  name:string[255];
end;

var myFile,streamFile: File;
th: THead;
ts: array of TSizes;
i:integer;
Buffer: array[0..255] of Byte;

begin
  if SaveDialog1.Execute then
  begin
    AssignFile(myFile, SaveDialog1.FileName);
    Rewrite(myFile);
    SetLength(ts,Memo1.Lines.Count);
    th.count := Memo1.Lines.Count;
    BlockWrite(myFile,th,1);
    for i:=0 to Memo1.Lines.Count-1 do
    begin
      ts[i].size := Get_File_Size(Memo1.Lines[i]);
      ts[i].name := TrimLength(GetFileName(Memo1.Lines[i]));
      BlockWrite(myFile,ts[i],1);

      //the code I need to help with
      AssignFile(streamFile, Memo1.Lines[i]);
      Reset(streamFile);
      while not Eof(streamFile) do begin
        BlockRead(streamFile,Buffer,1);
        BlockWrite(myFile,Buffer,1);
      end;
      CloseFile(streamFile);

    end;
    CloseFile(myFile);
  end;

And after I tried this, sometimes the file to be read is not completely written to the myFile,
and sometimes the streamFile isn't read at all.

Any solutions how to write file streams at the end of the current editing file ?

Member Avatar for Micheus

Hi Thew.

first, one of your problem is assigned to wrong value that You pass to Read/Writeblock buffer size parameter. You are using 1, that means You will read or write 1 Byte only - it's not true.

When You write ts, You are intend to write a TSizes structure and it has 4 + 255 (longword + string[255]) = 259 Bytes.

In that case You must to be using:
BlockWrite(myFile, ts[n], SizeOf(ts[n]));

second, when using Read/WriteBlock, You don't must use "while EOF(<file>) do" statement. It's to be used when You made use of the Read(ln)/Write(ln) file I/O functions.

In this case, You must read a block of bytes to a buffer and compare with the amount of bytes read with expected value. I think that a sample is more useful to help You to understand this. So take a look in this sample from Delphi help file to Blockread function:

var

  FromF, ToF: file;
  NumRead, NumWritten: Integer;
  Buf: array[1..2048] of Char;
begin
  if OpenDialog1.Execute then                               { Display Open dialog box }
  begin
    AssignFile(FromF, OpenDialog1.FileName);
    Reset(FromF, 1);	{ Record size = 1 }
    if SaveDialog1.Execute then                              { Display Save dialog box}
    begin
      AssignFile(ToF, SaveDialog1.FileName);	{ Open output file }

      Rewrite(ToF, 1);	{ Record size = 1 }
      Canvas.TextOut(10, 10, 'Copying ' + IntToStr(FileSize(FromF))
        + ' bytes...');
      repeat
        BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
        BlockWrite(ToF, Buf, NumRead, NumWritten);
      until (NumRead = 0) or (NumWritten <> NumRead);
        CloseFile(FromF);
        CloseFile(ToF);
    end;
  end;
end;

... and at last, You can use Seek function to set the start position that You will start to write a buffer. (take a look in the help file)

I hope to help you
Bye

Member Avatar for Thew

Thank you Micheus, I've used this help you posted to another file function FileWrite and FileRead ad it works great.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.