Hi all,
I was hoping someone could help me understand why and/or advise the best way to carry out my task at hand. I have an instrument I service for my company that creates text log files of every device command sent to and reply from and starts a new log once the actual working log file reaches 4MB in size. Well each field is comma separated so I guess you would call this a csv file. The instrument records roughly 6-10 command per millisecond. I have software on windows to review log files and filter them which I use to track down the root cause of when there are instrument errors/failure. Ok so I am writing my own log reviewer app in Lazarus because I want extra features to help speed up troubleshooting and think I can make a better app.
I am developing under Linux Ubuntu 8.1. My problem I am having is that loading a 4MB text file takes for ever! Using a textfile variable, assgnfile, reset, readln and closefile method is very slow!!! I just tried this method to open a 4MB text file (this file is 56,000 lines) and it took 27mins to get to the 26,000th line. I added a counter to update a label object to tell me what line it was up to. Also a listbox.items.loadfromfile is painfully slow. I have also found an example on delphi3000 for a line by line read (
http://www.delphi3000.com/articles/article_1363.asp?SK=) but this is still to slow for me (but it was faster). I run a asus mobo with a core 2 duo E8400 3GHz with 4GB ram and sata 2 hdd. Then my laptop which is a centrino 1.7Ghz, 500MB ram and maybe sata hdd, using the service software log reviewer app can read this 4MB text file, into its stringlist/stringgrid in 2sec!!!! Way, way, way faster.
Can anyone shed some light as to what my problem could be or the method more suitable to perform my task? I started to look a memory mapped file methods but my programming experience is not the high and would require me to do some more learning. But i am up for learning! Below is the fastest routine I have made so far. But I want a 4MB text file loading in seconds no minutes to hours.
AssignFile(F, fName); //Open up the text file as an untyped file
Reset(F, 1);
fSize := FileSize(fName); //Get the file size
pb.Max := fSize;
NewBuffer := '';
buffer := '';
lineCount := 0;
//while FilePos(F) <> fSize do
Repeat
//read in up to an 8K block
BlockRead(F, buf, BlockSize, BlockCount);
// Allocate the new buffer
GetMem(NewBuffer, BlockSize + 1);
// Copy the New Data Into The Buffer
StrPLCopy(NewBuffer, buf, BlockCount);
// Concat the buffers
Buffer := Buffer + NewBuffer;
// Return the buffer memory
FreeMem(NewBuffer);
// Step 2. Chop the data into a stringlist
while (Pos(#10, buffer) <> 0) do
begin
//showmessage('ok');
Application.ProcessMessages;
CutAt := Pos(#10, buffer);
Line := Copy(buffer, 1, CutAt);
Line := Trim(Line);
ListBox1.Items.Add(Line);
Delete(buffer, 1, CutAt);
Inc(lineCount);
Label1.Caption := 'Total Lines: ' + IntToStr(lineCount);
end;
//showmessage(IntToStr(FilePos(F)));
Inc(logCount);
pb.Position := BlockSize * logCount;
Until (BlockCount=0); //(logCount=20);
CloseFile(F); //close the file, you're done
showmessage(IntToStr(logCount)); }
Thanks in advance,
Paul.