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.
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.
create a TStringList and load the file with the funtion LoadFromFile.
Delete the lines and use SaveToFile
/ TK
Delete the lines and use SaveToFile
/ TK
Too late, Magik :P
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.
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...
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):b oolean;
procedure CopyFileAndFilter(aFN_FROM ,aFN_TO:st ring; 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.P as','Unit2 .txt',Filt );
/ / probably should erase the original file and rename new one here.
end;
type
tFilterFunc=function(aLine
procedure CopyFileAndFilter(aFN_FROM
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
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.P
/ / probably should erase the original file and rename new one here.
end;
Procedure DeleteFirst2AndLastLineOfF ile(FileNa me: 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(F ileName, '.old')); //if you wish
end;
Kind regards
Pierre
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(F
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(' YourFileNa me');
to save this back to the file:
Memo1.Lines.SaveToFile('Yo urFileName ');
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('
to save this back to the file:
Memo1.Lines.SaveToFile('Yo
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
var List:TStringList;
begin
List := TStringList.Create;
List.LoadFromFile('File.tx
// 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...