我有一个列表框,其中列出了文件夹中的所有文件。对于列表框的每个元素,我想运行一个函数。如果函数结果为false,那么我想将列表框项移动到名为ListBox_fisiere_restore_vme的单独列表框中。如果函数结果为true,那么我想将列表框项添加到名为ListBox_continut_ftp的列表框中。这应该很容易。问题是,无论函数结果如何,项目都会被移动到ListBox_fisiere_restore_vme中。
我用于每个列表框项目的功能:
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;
导致此问题的循环具有以下代码:
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;
我不知道我做错了什么。
答案 0 :(得分:1)
我怀疑你看到的问题与你在测试中串联延迟的循环运行有关。如果您正在测试100个文件,则需要100秒,每秒测试一个文件。一千个文件需要1000秒。如果任何给定的文件在检查时在那个一秒钟的窗口中没有变化,它将给出您正在观察的结果。
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;
将此行为与此方法进行比较,无论“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;
第一种方法就像试图击中一个移动的目标。第二种方法一次性捕获文件状态,并在相同的相对时间间隔内测量所有变化。运行只需几秒钟。
我怀疑后一种方法更接近你的意图。
答案 1 :(得分:0)
delay(interval)
多长时间?尽量增加它。
但这是错误的概念。如果delay(interval)
是100毫秒,这意味着您有超过一分半钟(100秒)来循环1000个文件。如果我是你,我会使用计时器和几个字符串网格而不是列表框。
每个2列字符串网格可以包含第0列中的文件名和第1列中的文件大小。四个网格 - stringGrid_continut_ftp, stringGrid__fisiere_restore_vme, stringGrid_old
和stringGrid_current
。
Timer1.timer
必须在stringGrid_current
中获取默认文件名和大小,并将其与stringGrid_old
进行比较,并且根据结果必须在前两个字符串网格中的一个中插入一行。最后stringGrid_old
必须包含stringGrid_current
的所有值,并且下一个计时器事件已准备好开始。
很抱歉只给出解释,但现在我已经厌倦了c ++,wix和批处理文件,无法专注于编写高质量的delphi代码。但我确定你会明白这一点。