Solved

Appending a block to a file

Posted on 1998-06-23
5
145 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 150 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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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…
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

726 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