Subject: CnMD5的进度回调函数怎么使用? [Print This Page]
Author:
yinsim Time: 2010-8-25 10:50 Subject: CnMD5的进度回调函数怎么使用?
var
FAbort: Boolean;
procedure TForm1.FormCreate(Sender: TObject);
begin
FAbort := False;
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
if dlgOpen1.Execute then
edt1.Text := MD5Print(MD5File(dlgOpen1.FileName, MD5CalcPrgssProc)));
end;
procedure TForm1.MD5CalcPrgssProc(ATotal, AProgress: Int64;
var Cancel: Boolean);
begin
pb1.Position := Round(AProgress / ATotal * 100);
Cancel := FAbort;
end;
这里实现了MD5的进度回调函数后,似乎实际调用后进度条没有变化,而实际获取到了文件的MD5值,即使只在回调函数里面只添加一条简单的ShowMessage都不显示,请问为什么?
Author:
Passion Time: 2010-8-25 13:03
加个Application.ProcessMessages;试一试?
Author:
yinsim Time: 2010-8-25 14:12
谢谢Passion这么快回复,辛苦了!
添加Application.ProcessMessages仍然无效.........
Author:
Passion Time: 2010-8-25 20:31
我们做MD5时默认的Buffer大小是4M,也就是进度的粒度是4M,小于4M的文件一次算完了,不会出现进度回调。
因此如果您的文件较小,那么不回调是正常现象。
如果要修改此粒度,可在CnMD5.pas中搜寻并修改 4096 * 1024 这个常量。
Author:
yinsim Time: 2010-8-26 08:13
我之前就试过大小文件,即使是几百M的文件,也是这种情况.
另外,按道理调用进度回调时如果把传入的变量CancelCalc为True,则在计算大于4M的文件时,在计算完首个4M后应该要中止才对,但是列程还是会继续,并计算出了正确的MD5值.
百思不得其解啊...
Author:
Passion Time: 2010-8-26 12:34
Oh,我看了一下代码,确实有问题。当初我们为提高计算速度,对于大小小于2G的直接进行了文件内存映射,根据内存地址去直接计算,这个直接计算的代码中是没有处理回调的。
如果要修补此问题,可以查找FileSizeIsLargeThan2G(FileName)此处调用改成False,便会用常规方式进行文件的分块读入并计算,此时回调应该有效。Cancel也应该会有效。
Author:
yinsim Time: 2010-8-26 15:43
嗯,终于可以有进度回调了,也可以中止了.不过是要将FileSizeIsLargeThan2G(FileName)这里直接改为True,而不是False,要不然还是使用内存映射.
谢谢Passion的耐心回复,另外内存映射方式有无可能也添加进度回调?
Author:
Passion Time: 2010-8-27 08:24
也不是不行。不过改动稍微有点大。
Welcome to CnPack Forum (http://bbs.cnpack.org/) |
Powered by Discuz! 5.0.0 |