Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way for read and write a text file

I am using the latest version of Lazarus IDE and I have a Memo1 on my TForm1. I have to load a text file in Memo1 and then edit every line of the Memo (I use Memo1.Lines.Strings[i] := ...). At the end I must save the edited memo at a particular path.

Question: I am looking for the faster way between:

  1. Load the whole text inside the memo, edit its content and save into a new file (load all -> edit all -> write all)
  2. Do a while loop (until the end of my *.txt file) that reads the file line by line, edit the content and save it in the new file. (load line -> edit -> write | load -> edit -> write | load line -> edit -> write | ...)

I am pretty new with Delphi developing, and I have also read some pages about TStringLists. My text file is going to have a lot of lines (It could have 5000+ lines) and I don't want that my program loses performance.

Any suggestion? Should I use TStringList or one of the two methods I listed before?

like image 566
Alberto Miola Avatar asked Jan 01 '14 22:01

Alberto Miola


People also ask

How do you open a file for both reading and writing?

'r+' opens the file for both reading and writing. On Windows, 'b' appended to the mode opens the file in binary mode, so there are also modes like 'rb', 'wb', and 'r+b'. Also reading then writing works equally well using 'r+b' mode, but you have to use f.

Which method is used to read data from a text file?

To read from a text file Use the ReadAllText method of the My. Computer. FileSystem object to read the contents of a text file into a string, supplying the path.


1 Answers

5000 lines isn't a lot, unless the strings are very long.

The easiest way is to use a TStringList. There's no need to use a GUI control unless the user needs to see or edit the content.

var
  SL: TStringList;
  i: Integer;
begin
  SL := TStringList.Create;
  try
    SL.LoadFromFile(YourFileNameHere);
    for i := 0 to SL.Count - 1 do
    begin
      SL[i] := IntToStr(i) + ' ' + SL[i];
      // Do any other processing
    end;

    SL.SaveToFile(YourFileNameHere);
  finally
    SL.Free;
  end;
end;

If (as you say in a comment above) you need to do this in a TMemo for testing purposes, you can do it the same way:

Memo1.Lines.LoadFromFile(YourFileNameHere);
for i := 0 to Memo1.Lines.Count - 1 do
  Memo1.Lines[i] := IntToStr(i) + ' ' + Memo1.Lines[i];
Memo1.Lines.SaveToFile(YourFileNameHere);

Of course, the easiest way to do this would be to write a procedure that accepts a plain TStrings descendent of any sort:

procedure AppendValueToStrings(const SL: TStrings; 
  StartingValue: Integer);
var
  i: Integer;
begin
  Assert(Assigned(SL));  // Make sure a valid TStrings has been passed in
  for i := 0 to SL.Count - 1 do
  begin
    SL[i] := IntToStr(StartingValue) + ' ' + SL[i];
    Inc(StartingValue);
  end;
end; 

Then you can call it with either one:

SL := TStringList.Create;
try
  SL.LoadFromFile(YourFileNameHere);
  AppendValueToStrings(SL, 10);
  SL.SaveToFile(YourFileNameHere);
finally
  SL.Free;
end;

Memo1.Lines.LoadFromFile(YourFileNameHere);
AppendValueToStrings(Memo1.Lines, 10);
Memo1.Lines.SaveToFile(YourFileNameHere);
like image 108
Ken White Avatar answered Sep 28 '22 22:09

Ken White