Link to home
Start Free TrialLog in
Avatar of fabyola
fabyola

asked on

Delete a Line from a File

I have a file with alot of lines in it. For example: File.txt

60M200407014708990506058       0022D03533203534
60A200407014708990506058       CANC000000007890
60A200407014708990506058       I   000000021980
60A200407014708990506058       1800000000020850
60A200407014708990403225       CANC000000035836

I want to open this file "File.txt" and delete for example the first 2 lines of the file and the last one. then it woul stay for example:

60A200407014708990506058       I   000000021980
60A200407014708990506058       1800000000020850

with no blank spaces on the line deleted.
Avatar of Wim ten Brink
Wim ten Brink
Flag of Netherlands image

You won't like the answer, I fear, but the easiest way is by using a stringlist...

var List:TStringList;
begin
  List := TStringList.Create;
  List.LoadFromFile('File.txt');
  // Delete last-to-first or else the index numbers get mised up.
  // Keep in mind, lists are 0-based...
  List.Delete(List.Count-1);
  List.Delete(1);
  List.Delete(0);
  List.SaveToFile('File.txt');
  List.Free;
end;

Other solutions that won't require you to read the whole file are a lot harder since you will actually have to move data around in the file. This means opening the file, finding the exact locations of the lines you want to remove and overwriting them with the data a bit further on... It would be possible to do and it would perform a bit faster, especially for huge files, but unfortunately it's not a simple solution...
Avatar of Magic55
Magic55

create a TStringList and load the file with the funtion LoadFromFile.
Delete the lines and use SaveToFile
/ TK
Too late, Magik :P
Avatar of fabyola

ASKER

I need a way to do it withou loading it into a StringList because the file is Too big. I need a way to open the file and edit it.
Avatar of fabyola

ASKER

Or it doesn´t matter how big the file is ?
Doing it without loading the whole thing in memory is a bit more complicated. There's just no easy solution for this. One way to do this is like this:

var
  FileIn, FileOut: TextFile;
  Line: string;
  LineCount: Integer;
begin
  AssignFile(FileIn, 'File.txt');
  Reset(FileIn);
  AssignFile(FileIn, 'File.new.txt');
  Rewrite(FileOut);
  LineCount := 0;
  while not EOF(FileIn) do begin
    Inc(LineCount);
    ReadLn(FileIn, Line);
    if (LineCount <> 1) and (LineCount <> 2) and (LineCount <> 3009) then WriteLn(FileOut, Line);
  end;
  CloseFile(FileIn);
  CloseFile(FileOut);
end;

The drawback is of course that you now have two large files. You'll have to delete one and rename the other afterwards...

There's also an option by using only one file variable. Either as a file of byte or just as a plain file. (of nothing) But then you have to determine in your code where lines end and move data to the beginning, overwriting the parts that you want to be removed. Finally you'd have to truncate the file to it's new length. This is quite a bit complex code, though...
I did something similar...it's a copy procedure that takes a "filter" to select which lines to keep. It will work for any size file, as long as you have the disk space...

type
  tFilterFunc=function(aLine:string):boolean;

procedure CopyFileAndFilter(aFN_FROM,aFN_TO:string; aFilter:tFilterFunc);
var
  F,C:textfile;
  Line:String;
begin
  {$I-}
  assignfile(F,aFN_FROM);   {Get file}
  reset(F);
  assignfile(C,aFN_TO);
  rewrite(C);
  while not eof(F) do begin
    readln(F,Line);
    if aFilter(Line) then
      writeln(C,Line);
  end;
  closefile(C);
  closefile(F);
end;

function Filt(aLine:string):boolean; far;
begin
  Result:=pos('A',aline)=0;  //any kind of test you want, return RESULT=TRUE to keep the line.
end;

procedure DoItNow;
begin
  CopyFileAndFilter('Unit2.Pas','Unit2.txt',Filt);
 / / probably should erase the original file and rename new one here.
end;
Procedure DeleteFirst2AndLastLineOfFile(FileName: string);
var OrigFile,NewFile: File;
    s: string;
begin
  AssignFile(NewFile, FileName);
  AssignFile(OrigFile, ChangeFileExt(FileName, '.old'));

  Reset(OrigFile);
  Rewrite(NewFile);

  //skip 1st two lines
  readln(OrigFiles);
  readln(OrigFiles);

  While Not Eof(OrigFile) do
  begin
    readln(OrigFile,s);
    if Not Eof(OrigFile) then writeln(NewFile,s); //only write it if not the last line
  end;
 
  CloseFile(OrigFile);
  CloseFile(NewFile);
  DeleteFile(ChangeFileExt(FileName, '.old')); //if you wish
end;

Kind regards
Pierre
Sorry, LRHGuy. Didn't read all the comments before posting mine.
>> I need a way to do it withou loading it into a StringList because the file is Too big. I need a way to open the file and edit it.
didn't quite understood how you want to edit it.

if manually then:

use a TMemo component. to load the file into the memo:
Memo1.Lines.LoadFromFile('YourFileName');

to save this back to the file:
Memo1.Lines.SaveToFile('YourFileName');
ASKER CERTIFIED SOLUTION
Avatar of Wim ten Brink
Wim ten Brink
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial