W
wuan
Unregistered / Unconfirmed
GUEST, unregistred user!
我用文件流的方法完成文件copy,还想在主窗体上显示进度(注意为了提高速度直接应用的f2.copyfrom(f1,0)而不是f.readbuf与f.writebuf)于是我将f2.copyfrom(f1,0)放入副线程,基本可以实现小文件copy,但发现文件超过100M就会出现副线程意外终止错误而无法继续,每次错误出现的位置不定(有时是考到40%处,有时是考到80%处。。。有时可以完成)
说明一下:如果用单线程f2.copyfrom(f1,0)文件很大也没问题。
下面是代码,请高手指出原因:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, ComCtrls, ExtCtrls, StdCtrls, Gauges;
type
TForm1 = class(TForm)
Panel1: TPanel;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
GroupBox1: TGroupBox;
Edit1: TEdit;
Edit2: TEdit;
Source: TBitBtn;
BitBtn2: TBitBtn;
opd: TOpenDialog;
svd: TSaveDialog;
pb1: TGauge;
procedure SpeedButton3Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure SourceClick(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
f1,f2:Tfilestream;
s,t:string;
implementation
uses
unit2;
{$R *.dfm}
var
th:mypath;
j:bool;
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
speedbutton2.Enabled:=true;
s:=edit1.text;
t:=edit2.text;
try
f1:=TFILEStream.Create(s,fmopenread);
Pb1.MaxValue:=f1.Size;
f2:=tfilestream.Create(t,fmopenwrite or fmcreate);
th:=mypath.Create(true);
th.Resume;
while pb1.Progress<pb1.MaxValuedo
begin
application.ProcessMessages;
pb1.Progress:=f2.size;
end;
speedbutton2.Enabled:=false;
showmessage('hh');
th.Destroy;
finally
f1.Free;
f2.free;
end;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
close;
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
j:=not j;
if j then
begin
speedbutton2.Caption:='&contious';
th.Suspend;
end
else
begin
speedbutton2.Caption:='&pause';
th.Resume;
end;
end;
procedure TForm1.SourceClick(Sender: TObject);
begin
if opd.Execute then
edit1.Text:=opd.FileName;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
svd.DefaultExt:=extractfileext(edit1.Text);
if svd.Execute then
edit2.Text:=svd.FileName;
end;
end.
unit Unit2;
interface
uses
Classes,unit1;
type
mypath = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
end;
implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure mypath.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ mypath }
procedure mypath.Execute;
begin
try
unit1.f2.CopyFrom(unit1.f1,0);
finally
end;
end;
end.
说明一下:如果用单线程f2.copyfrom(f1,0)文件很大也没问题。
下面是代码,请高手指出原因:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, ComCtrls, ExtCtrls, StdCtrls, Gauges;
type
TForm1 = class(TForm)
Panel1: TPanel;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
GroupBox1: TGroupBox;
Edit1: TEdit;
Edit2: TEdit;
Source: TBitBtn;
BitBtn2: TBitBtn;
opd: TOpenDialog;
svd: TSaveDialog;
pb1: TGauge;
procedure SpeedButton3Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure SourceClick(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
f1,f2:Tfilestream;
s,t:string;
implementation
uses
unit2;
{$R *.dfm}
var
th:mypath;
j:bool;
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
speedbutton2.Enabled:=true;
s:=edit1.text;
t:=edit2.text;
try
f1:=TFILEStream.Create(s,fmopenread);
Pb1.MaxValue:=f1.Size;
f2:=tfilestream.Create(t,fmopenwrite or fmcreate);
th:=mypath.Create(true);
th.Resume;
while pb1.Progress<pb1.MaxValuedo
begin
application.ProcessMessages;
pb1.Progress:=f2.size;
end;
speedbutton2.Enabled:=false;
showmessage('hh');
th.Destroy;
finally
f1.Free;
f2.free;
end;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
close;
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
j:=not j;
if j then
begin
speedbutton2.Caption:='&contious';
th.Suspend;
end
else
begin
speedbutton2.Caption:='&pause';
th.Resume;
end;
end;
procedure TForm1.SourceClick(Sender: TObject);
begin
if opd.Execute then
edit1.Text:=opd.FileName;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
svd.DefaultExt:=extractfileext(edit1.Text);
if svd.Execute then
edit2.Text:=svd.FileName;
end;
end.
unit Unit2;
interface
uses
Classes,unit1;
type
mypath = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
end;
implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure mypath.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ mypath }
procedure mypath.Execute;
begin
try
unit1.f2.CopyFrom(unit1.f1,0);
finally
end;
end;
end.