?
Solved

Appending a block to a file

Posted on 1998-06-23
5
Medium Priority
?
148 Views
Last Modified: 2010-05-18
I have developed a component to read an rpt (ReportSmith) file, and change the hard-coded paths within it so that my report points to the correct set of data.  

It works perfectly, but I am reading it in as a File of Byte and writing it back to a new file, and all this takes a long time if it is a big file, especially if there are graphics within the Report.

I have discovered that I don't have to go through the whole file - just the first bit of it which has the embedded paths.

My question is - how can I stop reading in byte by byte when I have done the changes and just append the rest of the original file from that point.  (OR if I were to block read the first part into memory, how would I read it and manipulate it in memory and then write it back).

0
Comment
Question by:jdthedj
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 3

Accepted Solution

by:
vladika earned 600 total points
ID: 1355358
Use class TFileStream

for example
procedure TForm1.Button1Click(Sender: TObject);
var FileStream: TFileStream;
    S: string;
begin
  FileStream := TFileStream.Create('c:\test.txt', fmOpenReadWrite);
  try
    FileStream.Position := 4;  // set offset into the stream for reading and writing
    SetString(S, nil, 4);  // allocate space for S (for example 4 bytes)
    FileStream.Read(PChar(S)^, 4); // read 4 bytes from filestream into S
    if S = '1234' then S := '4321' else S := '1234';  // correct S
    FileStream.Position := 4;  // set old position
    FileStream.Write(PChar(S)^, 4);  // write correct S into file stream
  finally
    FileStream.Free;  // the end
  end;
end;


0
 
LVL 3

Expert Comment

by:vladika
ID: 1355359
If you want test my procedure then create manually file c:\test.txt
0
 
LVL 3

Author Comment

by:jdthedj
ID: 1355360
Hi Valdika - Thanks for your help

Sorry  - but I forgot to mention I am using D1 and WFW 3.11, so I haven't got the SetString command.

I'm not sure if reading the data as strings would work because a lot of the bytes are outside the normal character range.

I am happy to read the first part in byte by byte as I have been doing, because the data to be read back may have added bytes or fewer bytes.  I want to append the whole of the rest of the file in one hit if possible, or in large chunks after fixing up the first part of the file.


0
 
LVL 3

Expert Comment

by:vladika
ID: 1355361
Hi Jdthedj

1) You may use not only string. Read, Write, ReadBuffer, WriteBuffer methods
works with ANY BUFFER, I use string as buffer only for example.

2) To copy the rest of one stream into other stream use CopyFrom method
Here is example

procedure TForm1.AnalizeAndReplace(SrcName, DstName: string);
var SrcStream, DstStream: TFileStream;
    B: Byte;
    S: string;
begin
  SrcStream := TFileStream.Create(SrcName, fmOpenRead); { Source file stream }
  try
    DstStream := TFileStream.Create(DstName, fmCreate); { Dest file stream }
    try
      while SrcStream.Position < SrcStream.Size do { while not end of file }
      begin
        SrcStream.Read(B, 1);  { read one Byte }
        { your code for analize B
          for example search Char(B) = 'A'
          when found insert into DstStream 'I found' and
          copy rest }
        if Char(B) = 'A' then
        begin
          S := 'I found';
          DstStream.Write(S[1], Length(S)); { write S into Stream, I use string as buffer only for example}
          Break; { exit from while }
        end;
        DstStream.Write(B, 1);  {copy B into DstStream }
      end;
      { copy rest }
      if SrcStream.Position < SrcStream.Size then
        DstStream.CopyFrom(SrcStream, SrcStream.Size - SrcStream.Position);
    finally
      DstStream.Free;
    end;
  finally
    SrcStream.Free;
  end;
end;

{ How to use }
procedure TForm1.Button1Click(Sender: TObject);
begin
  AnalizeAndReplace('c:\src.dat', 'c:\dst.dat'); { src file name and dest file name }
end;


0
 
LVL 3

Author Comment

by:jdthedj
ID: 1355362
Hi Vladika

Thanks a lot for all your help.  You have explained it very clearly.  It is a lot easier to program when you can understand what you are doing!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question