CnPack Forum


 
Subject: CnMD5的进度回调函数怎么使用?
yinsim
新警察
Rank: 1



UID 50783
Digest Posts 0
Credits 48
Posts 16
点点分 48
Reading Access 10
Registered 2010-8-17
Status Offline
Post at 2010-8-25 10:50  Profile | Blog | P.M. 
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都不显示,请问为什么?
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6838
Posts 3591
点点分 6838
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2010-8-25 13:03  Profile | Blog | P.M. 
加个Application.ProcessMessages;试一试?
Top
yinsim
新警察
Rank: 1



UID 50783
Digest Posts 0
Credits 48
Posts 16
点点分 48
Reading Access 10
Registered 2010-8-17
Status Offline
Post at 2010-8-25 14:12  Profile | Blog | P.M. 
谢谢Passion这么快回复,辛苦了!

添加Application.ProcessMessages仍然无效.........
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6838
Posts 3591
点点分 6838
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2010-8-25 20:31  Profile | Blog | P.M. 
我们做MD5时默认的Buffer大小是4M,也就是进度的粒度是4M,小于4M的文件一次算完了,不会出现进度回调。
因此如果您的文件较小,那么不回调是正常现象。

如果要修改此粒度,可在CnMD5.pas中搜寻并修改 4096 * 1024 这个常量。
Top
yinsim
新警察
Rank: 1



UID 50783
Digest Posts 0
Credits 48
Posts 16
点点分 48
Reading Access 10
Registered 2010-8-17
Status Offline
Post at 2010-8-26 08:13  Profile | Blog | P.M. 
我之前就试过大小文件,即使是几百M的文件,也是这种情况.

另外,按道理调用进度回调时如果把传入的变量CancelCalc为True,则在计算大于4M的文件时,在计算完首个4M后应该要中止才对,但是列程还是会继续,并计算出了正确的MD5值.

百思不得其解啊...
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6838
Posts 3591
点点分 6838
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2010-8-26 12:34  Profile | Blog | P.M. 
Oh,我看了一下代码,确实有问题。当初我们为提高计算速度,对于大小小于2G的直接进行了文件内存映射,根据内存地址去直接计算,这个直接计算的代码中是没有处理回调的。

如果要修补此问题,可以查找FileSizeIsLargeThan2G(FileName)此处调用改成False,便会用常规方式进行文件的分块读入并计算,此时回调应该有效。Cancel也应该会有效。
Top
yinsim
新警察
Rank: 1



UID 50783
Digest Posts 0
Credits 48
Posts 16
点点分 48
Reading Access 10
Registered 2010-8-17
Status Offline
Post at 2010-8-26 15:43  Profile | Blog | P.M. 
嗯,终于可以有进度回调了,也可以中止了.不过是要将FileSizeIsLargeThan2G(FileName)这里直接改为True,而不是False,要不然还是使用内存映射.

谢谢Passion的耐心回复,另外内存映射方式有无可能也添加进度回调?
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6838
Posts 3591
点点分 6838
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2010-8-27 08:24  Profile | Blog | P.M. 
也不是不行。不过改动稍微有点大。
Top
 




All times are GMT++8, the time now is 2024-11-24 06:17

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.0.0  © 2001-2006 Comsenz Inc.
Processed in 0.008328 second(s), 9 queries , Gzip enabled

Clear Cookies - Contact Us - CnPack Website - Archiver - WAP