Reputation: 255
I have a listbox in which I list all files from a folder. For each element of the listbox I want to run a function. If the function result is false then I want to move the listbox item into a separate listbox called ListBox_fisiere_restore_vme. If the function result is true then I want to add the listbox item into a listbox called ListBox_continut_ftp. This should be ease to do.The problem is that no matter the function result the item is allways moved into the ListBox_fisiere_restore_vme.
The function i use for each listbox item:
function GetFileSize_mmg(const FileName: string): Int64;
var
fad: TWin32FileAttributeData;
begin
if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad) then RaiseLastOSError;
Int64Rec(Result).Lo := fad.nFileSizeLow;
Int64Rec(Result).Hi := fad.nFileSizeHigh;
end;
function does_size_changes(nume_fisier: string; interval: integer;Memo_loguri: TMemo): boolean;
var
size1, size2: Int64;
begin
size1:=0;
size2:=0;
size1 := GetFileSize_mmg(nume_fisier);
delay(interval);
size2 := GetFileSize_mmg(nume_fisier);
if size1 <> size2 then
begin
Result := true;
Memo_loguri.Lines.Add(datetimetostr(now) + ' - filename "'+nume_fisier+'" grows');
end
else
begin
Result := false;
Memo_loguri.Lines.Add(datetimetostr(now) + ' - filename "'+nume_fisier+'" is not in use');
end;
end;
The loop that causes this issue has the following code:
procedure Tform2.OnSchedule_1_Trigger(Sender: TScheduledEvent);
var
nume_fisier:string;
i:integer;
begin
listbox_fisiere_in_uz.Clear;
listbox_fisiere_restore_vme.Clear;
DSiEnumFilesToSL(edit_watch_folder.text+edit_masca_fisiere.text, 0, listbox_fisiere_in_uz.Items, true, false );
for i := ListBox_fisiere_in_uz.Items.count - 1 downto 0 do
begin
if does_size_changes(ListBox_fisiere_in_uz.Items[i], 1000, Memo_loguri) then
begin
listbox_continut_ftp.Items.Add(ListBox_fisiere_in_uz.Items[i]);
end
else
begin
ListBox_fisiere_restore_vme.Items.Add(ListBox_fisiere_in_uz.Items[i]);
end;
end;
I don't see where I'm doing it wrong.
Upvotes: 0
Views: 1482
Reputation: 1844
I suspect the problem you're seeing is related to the fact that you're running through the loop with the delay in series with the tests. If you have 100 files you're testing, it'll take 100 seconds, with one file tested every second. One thousand files will take 1000 seconds. If any given file doesn't change in that one-second window when it's examined, it'll give the results you're observing.
for i := 0 to n-1 do
begin
s1 := sizeoffile( fn[i] );
delay( 1000 ); // pause one second
s2 := sizeoffile( fn[i] );
if (s1 <> s2) then
addToLog( 'file size of '+fn[i]+' DID change' )
else
addToLog( 'file size of '+fn[i]+' did NOT change' )
end;
Compare that behavior to this approach that will only take seconds to run regardless of 'n':
var
initialFileSize, newFileSize : array of Int64;
. . .
// get initial file sizes
for i := 0 to n-1 do
initialFileSize[i] := sizeoffile( fn[i] );
delay( 1000 ); // pause one second
// get new file sizes
for i := 0 to n-1 do
newFileSize[i] := sizeoffile( fn[i] );
for i := 0 to n-1 do
begin
if (initialFileSize[i] <> newFileSize[i]) then
addToLog( 'file size of '+fn[i]+' DID change' )
else
addToLog( 'file size of '+fn[i]+' did NOT change' )
end;
The first approach is like trying to hit a moving target. The second approach captures the file states all at once, and measures changes all in the same relative gap of time. It will take only a few seconds to run.
I suspect the latter approach is closer to what you're intending.
Upvotes: 1
Reputation: 1123
How long is delay(interval)
? Try to increase it.
But this is wrong concept. If delay(interval)
is 100 msec this means you have more than minute and a half (100 sec) to loop 1000 files. If I were you I'd use a timer and few string grids instead of listboxes.
Each 2 column string grid can contain file name in column 0 and file size in column 1. Four grids - stringGrid_continut_ftp, stringGrid__fisiere_restore_vme, stringGrid_old
and stringGrid_current
.
Timer1.timer
must get the default file names and sizes in stringGrid_current
, compare them with stringGrid_old
and and depending on result must insert a row in one of the first two string grids. At the end stringGrid_old
must have all values from stringGrid_current
and next timer event is ready to start.
Sorry for giving explanation only but right now I'm too tired of c++, wix and batch files and cannot focus to write quality delphi code. But I'm sure you'll get the idea.
Upvotes: 0