文件下载的一个问题

kulv0405 2005-08-26 03:40:37
所用函数:UrlDownloadToFile();
为下载建立了一个线程,为了实现进度条,自己封装了IBInstatusCallBack这个接口.
当文件正在下载中的时候点'取消'按钮,'下载'按钮变为'重新下载',线程终止,但那个未下载完的文件不能删除,说什么正在使用中..所以我点'重新下载'按钮时,无法下载/..

说白了就是在当下载被终止时,怎么删除或移动那个未下载完的文件...我用了MoveFileEx(),但对它也没有效果.....如果不把它删除,无法重新下载..
...全文
213 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
kulv0405 2005-08-30
  • 打赏
  • 举报
回复
nowUpdata.Suspend; //线程睡眠
if MessageDlg('确定要取消更新吗?',
mtConfirmation,[mbYes,mbNo],0)=mrYes then
begin
nowUpdata.Terminate;//线程终止

线程肯定是终止了,但是,UrlDownloadToFile()这个函数的句柄没有释放,占用了下载文件的文件名,造成了无法停止后继续更新,,关键是不知道怎么释放那个句柄..
cqzyf 2005-08-30
  • 打赏
  • 举报
回复
当文件正在下载中的时候点'取消'按钮,'下载'按钮变为'重新下载',线程终止,
nowUpdata.Terminate;过程能不能终止线程取决于你的下载的代码
一般下载时用 while not Terminated do
begin
....
end;
因为nowUpdata.Terminate只是设定设定Terminated = true;所以从你的问题看八成是线程更本没有
中止,打开的文件没有关闭
smiler007 2005-08-26
  • 打赏
  • 举报
回复
先做个记号
kulv0405 2005-08-26
  • 打赏
  • 举报
回复
线程终止,这个函数也就终止了.... 我试了,不行..
leonkim 2005-08-26
  • 打赏
  • 举报
回复
应该是因为
UrlDownloadToFile( nil,
Pchar(Source),
Pchar(Dest),
0,
RevedByte )
函数占用文件名造成的。

你在删除前sleep(5000)一下试试
kulv0405 2005-08-26
  • 打赏
  • 举报
回复
//------------------------------------------------------------------------------
//更新按纽
//------------------------------------------------------------------------------
procedure TForm1.suiButton1Click(Sender: TObject);
begin
suiButton1.Enabled := false;
ArDownload := false;
CrThread := false;
CurDown := 0;
if finish = true then
begin
Label1.Caption := '已经更新完毕...' ;
Label2.Visible := false;
suiButton1.Enabled := true;
exit;
end;
if UpdateFile( SourcePath, ServerIniFile ) then
begin
filecount := 1;
Label1.Caption := '找到更新,正在下载更新文件,请稍侯...' ;
suiProgressBar1.Position := 0;
nowUpdata := Updata.Create( false );
nowUpdata.FreeOnTerminate := true;
CrThread := true;
end
else
ResumeFrm;
if Not ArDownload then
begin
Label1.Caption := '服务器连接失败,无法完成更新!';
Application.MessageBox('服务器连接失败,无法完成更新!','更新',16);
end;
end;
//------------------------------------------------------------------------------
//取消按纽
//------------------------------------------------------------------------------
procedure TForm1.suiButton2Click(Sender: TObject);
begin
if CrThread then
begin
nowUpdata.Suspend;
if MessageDlg('确定要取消更新吗?',
mtConfirmation,[mbYes,mbNo],0)=mrYes then
begin
nowUpdata.Terminate;
ResumeFrm;
RevedByte.Free;
FormCreate(Sender);
suiButton1.caption := '重新下载';
if MoveFileEx( pchar(DestFile),
nil,
MOVEFILE_REPLACE_EXISTING) then showmessage('ok');
exit;
end
else
begin
nowUpdata.Resume;//唤醒此线程
exit;
end;
end;
Application.Terminate;
end;

end.


线程启动时执行 ReadUpdateMessage()这个函数.
kulv0405 2005-08-26
  • 打赏
  • 举报
回复
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SUIButton, SUIProgressBar, SUIMgr, ExtCtrls, SUIForm, Inifiles,
IBInstatusCallBack, UrlMon, StdCtrls, ComCtrls, shellapi;

type
TForm1 = class(TForm)
suiForm1: TsuiForm;
suiBuiltInFileTheme1: TsuiBuiltInFileTheme;
suiProgressBar1: TsuiProgressBar;
suiButton1: TsuiButton;
suiButton2: TsuiButton;
Label1: TLabel;
Label2: TLabel;
procedure suiButton2Click(Sender: TObject);
procedure suiButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure ResumeFrm;
public
{ Public declarations }
ServerIniFile, LocalIniFile : string;
ArDownload, CrThread : boolean; //测试是否已经下载
filecount,CurDown : integer;
Updatefiles : TStrings;
finish : boolean;//文件是否已经下载
finished : boolean;//早已更新

function UpdateFile( Source,Dest : string ) : Boolean;
function ReadUpdateMessage( inifile: string;
var UpdateLst:Tstrings ) : Boolean;
end;

var
Form1 : TForm1;
RevedByte : TBindStatusCallback ;
const
SectionStr = 'Updatefiles';
SourcePath = 'http://www.emedisystem.com/test/update.ini';
MainUrl = 'http://www.emedisystem.com/test/';

implementation

uses Updata_, CRC;

{$R *.dfm}
var
nowUpdata : Updata;//线程
//------------------------------------------------------------------------------
//窗体初始化
//------------------------------------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
var
TempPath : array[0..255] of char;
Tpath : string;
ini : TInifile;
begin
RevedByte := TBindStatusCallback.Create;//控制进度条.
Label1.Caption := '点击┏更新┓按钮开始升级';
Label2.Visible := false;
finish := false;
finished := false;

GetTempPath( 256, TempPath );
Tpath := TempPath;
Tpath := Trim( Tpath );
if Copy( Tpath, Length(Tpath), 1 ) <> '\' then
Tpath := Tpath + '\';
ServerIniFile := Tpath + 'update.ini';
LocalIniFile := Extractfilepath( Application.exename ) + 'Predate.ini';
if not FileExists( LocalIniFile ) then
begin
ini := TInifile.Create( LocalIniFile );
ini.WriteString('Message','Update','');
ini.WriteDateTime('Message','Update',strtodatetime('2003-2-12 4:00:12'));
ini.Free;
end;
end;
//------------------------------------------------------------------------------
//读取更新信息
//------------------------------------------------------------------------------
function TForm1.ReadUpdateMessage( inifile: string;
var UpdateLst: Tstrings ) : Boolean;
var
ini, Mini : TIniFile;
SectionLst : TStrings;
str : string;
CRC32 : LongInt;
allStr,Source,Dest : string;
i ,j : integer;
UpDate,NowDate : TdateTime;
procedure Error;
begin
Application.MessageBox('Open error.', 'I/O Error', mb_Ok or mb_IconStop)
end;
begin
Result := false;
j := 1;
Mini := TInifile.Create( LocalIniFile );
UpDate := strtodatetime( Mini.ReadString('Message','UpDate','') );
ini := TInifile.Create( ServerIniFile );
NowDate := strtodatetime( ini.ReadString('Time','UpDateTime','') );
if Update >= NowDate then
begin
Mini.Free;
ini.Free;
finish := true;
finished := true;
nowUpdata.Terminate;
ResumeFrm;
Exit;
end;
SectionLst := TStringList.Create;
ini.ReadSection( SectionStr, SectionLst );
filecount := SectionLst.Count;
for i := 1 to filecount do
begin
Label1.Caption := format( '正在下载第%d个更新文件:',[i]);
allStr := ini.ReadString( SectionStr,SectionLst.Strings[i-1],'' );
Source := MainUrl + allstr;
Dest := ExtractFilePath( Application.ExeName ) + allstr;
if Not UpdateFile( Source, Dest ) then
begin
Result := false;
Label1.Caption := '更新失败...';
Label2.Visible := false;
suiProgressbar1.Position := 0;
CrThread := false;
suiButton1.Enabled := true;
finish := false;
exit;
end
else //crc校验
begin
str := ini.ReadString( 'Crc32', inttostr(j), '' );
if not FileCRC32( Dest, CRC32 ) then
begin
Error;
Exit;
end
else
begin
if inttostr(CRC32) = str then
Result := true
else
begin
Result := false;
Application.MessageBox( '文件CRC错误,请重新下载.',
'Error',
mb_Ok or
mb_IconStop);
Label1.Caption := '更新失败...';
Label2.Visible := false;
suiProgressbar1.Position := 0;
CrThread := false;
suiButton1.Enabled := true;
finish := false;
exit;
end;
end;
end;
CurDown := i;
end;
Mini.WriteString( 'Message','Update',datetimetostr(Nowdate) );
Mini.Free;
ini.Free;
nowUpdata.Terminate;
ResumeFrm;
end;
//------------------------------------------------------------------------------
//更新完成后的窗体
//------------------------------------------------------------------------------
procedure TForm1.ResumeFrm;
begin
CrThread := false;
suiButton1.Enabled := true;
if FileExists( ServerIniFile ) then
Deletefile( ServerIniFile );
if finished = true then
label1.Caption := '已经更新完毕...'
else
begin
Label1.Caption := '升级完成,谢谢使用...';
end;
suiButton2.Caption := '退出';


if GetForeGroundWindow <> Application.Handle then
SetForeGroundWindow( Application.Handle );
end;
//------------------------------------------------------------------------------
//下载文件
//------------------------------------------------------------------------------
function TForm1.UpdateFile( Source, Dest: string ) : Boolean;
begin
if UrlDownloadToFile( nil,
Pchar(Source),
Pchar(Dest),
0,
RevedByte ) = 0 then
Result := True
else
Result := False;
end;
xixuemao 2005-08-26
  • 打赏
  • 举报
回复
那把你的那段代码帖出来看看。
kulv0405 2005-08-26
  • 打赏
  • 举报
回复
不行啊,那个未下载完的文件跟这个程序好象还有关联,,无法删除/..
xixuemao 2005-08-26
  • 打赏
  • 举报
回复
你在删除前sleep(5000)一下试试呢?

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧