I am trying to create a new .txt file after a certain number of entries in an existing .txt file. I would like to have, for example, 50 entries in my file and then, after that, I would like a new file to be created and that the entries continue in that new file. Let us say that I don't want my log files to be filled with a lot of lines, but to have instead more .txt files where entries would be divided.
Here is my example code:
procedure TForm1.Button3Click(Sender: TObject);
function CountRows(Afilename: string): integer;
var
f: TextFile;
i: integer;
begin
assignfile(f, afilename);
reset(f);
result := 0;
while not eof(f) do
begin
readln(f);
inc(result);
end;
closefile(f);
end;
var
f: TextFile;
fileName: String;
fs: Tformatsettings;
begin
fs.shortdateformat := 'DD.MM.YYYY';
fs.TimeSeparator := ':';
filename := 'D:\LogLprf\LogLpFr ' Datetostr(now, fs) '.txt';
assignfile(f, filename);
if FileExists(filename) then
begin
if CountRows(filename)>=2 then
begin
filename := 'D:\LogLprf\LogLpFr ' Datetostr(now, fs) '1.txt';
assignfile(f, filename);
rewrite(f);
end
else
append(f);
end
else
begin
rewrite(f);
end;
fs.ShortDateFormat := 'DD.MM.YYYY HH:mm:ss';
Writeln(f, datetimetostr(now, fs) '- ' 'Some error...');
closefile(f);
end;
With the above code I manage to create the first file and to create the second one if the limit of the entries is reached in the first file. But, the second file keeps re-creating every time. I know that is because I am calling rewrite(f)
but I need that to create a new .txt file after the entries for the previous file reach their end. I have also tried calling the fileexists(filename)
after CountRows(filename)
but that is not a good solution as I will have a lot of nested if statements and that will not solve the issue if we need to create a lot of .txt files.
I have also tried going through loops, but that also doesn't solve the problem.
Any suggestions are wlcome...thank you
CodePudding user response:
When you are defining the file name you are using DateToStr which only adds date information into your file name. So if you try to create new filename multiple times in one day you will always get the same file name since DateToString
will return same result each time.
Instead of using DateToString
you should use DateTimeToString as this would also include time information iinto the result and thus allow you to create multiple distinct file names in the same day. And unless you need to create multiple new file names in a single second you won't have any problem with this.
Another approach would be incrementally numbering your files so that each file name contains a unique number at the end.
You can find solution on how to achieve this here
Or you could also combine yours with automatic incremental numbering approach if you need more user friendly file naming system.
CodePudding user response:
I don't have a running environment right now to test your code, but I think you can try something like that :
function GetFilesCount(SearchDir, SearchFile : String) : Integer;
var
SearchRec: TSearchRec;
begin
Result := 0;
if FindFirst(SearchDir SearchFile, faAnyFile xor faDirectory, SearchRec)= 0 then
begin
repeat
Inc(Result);
until (FindNext(SearchRec) <> 0);
Windows.FindClose(SearchRec.FindHandle);
end;
end;
procedure TForm1.Btn3Click(Sender: TObject);
var
FileCont: TStringList;
FileName, S: String;
fs: Tformatsettings;
C : Integer;
begin
FileCont := TStringList.Create;
try
fs.shortdateformat := 'DD.MM.YYYY';
fs.TimeSeparator := ':';
FileName := 'D:\LogLprf\LogLpFr ' Datetostr(Now(), fs) '.txt';
if FileExists(FileName) then
begin
FileCont.LoadFromFile(FileName);
if FileCont.Count >=2 then
begin
//Count previous log files.
C := GetFilesCount('D:\LogLprf\', 'LogLpFr*.txt');
Inc(C);
Filename := 'D:\LogLprf\LogLpFr ' Datetostr(Now(), fs) IntToStr(C) '.txt';
FileCont.Clear();
end;
end;
fs.ShortDateFormat := 'DD.MM.YYYY HH:mm:ss';
S := DateTimeToStr(Now(), fs) '- ' 'Some error...';
FileCont.Add(S);
FileCont.SaveToFile(Filename);
finally
FileCont.Free();
end;
end;