Текущий архив: 2003.03.27;
Скачать: CL | DM;
ВнизКак возобновить копирование файла после падения локальной сети Найти похожие ветки
← →
D.V.K (2003-01-23 13:28) [0]Недавно писал программу для копирования файла(ов) по локальной сети. Поскольку копировать надо большие файлы (фильмы, например), а сеть довольно медленная (10М), то есть возможность обрыва. Написал собственную процедуру копирования файлов по блокам. Если не смог передать очередной блок, то выдаю диалог, типа Abort-Retry-Ignore. Если Retry-пытаюсь передать блок снова. Для проверки в середине копирования файла выдираю сетевой разъём у своего компьютера. Программа зависает на 1/2 минуты. Затем выдаёт диалог. Я вставляю на место сетевой разъём. Но Retry программа делать не хочет - пишет ошибка доступа к файлу. Самое смешное, что даже после выхода из моей программы уже скопированную на компьютер-получатель часть файла невозможно удалить без перезагрузки компьютера-получателя.
Если кто сталкивался с подобной проблемой - помогите, пожалуйста.
← →
Digitman (2003-01-23 14:01) [1]Код приводи. Нет никакой проблемы, что-то неправильно делаешь
← →
D.V.K (2003-01-24 06:53) [2]Привожу код.
unit Unit7;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TCopyf = class(TForm)
pb1: TProgressBar;
Froml: TLabel;
Tol: TLabel;
Cancelb: TButton;
Nofsl: TLabel;
procedure FormActivate(Sender: TObject);
procedure CancelbClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Copyf: TCopyf;
fCancel:boolean;
implementation
uses Unit1;
{$R *.DFM}
procedure TCopyf.FormActivate(Sender: TObject);
var i,r,cc,tc,curdir,nofs,curfile:integer;
buf:array[0..16383] of byte;
fst:TFileStream;
fn2:string;
hf1:tHandle;
fnewal:boolean;
const dirnames:string="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
begin
fCancel:=false;
curdir:=0;
fnewal:=true;
nofs:=0;
for i:=0 to lb1.items.count-1 do if lb1.selected[i] and (lb1.items[i]<>"-") then inc(nofs);
if nofs=0 then
begin MessageBox(handle,"No items selected","Error",MB_OK or MB_ICONERROR);
PostMessage(handle,WM_CLOSE,0,0); exit; end;
curfile:=1;
for i:=0 to lb1.items.count-1 do if lb1.selected[i] then
if (lb1.items[i]="-") then fnewal:=true else
begin
if fCancel then continue;
pb1.Position:=0;
repeat
hF1:=CreateFile(pchar(lb1.items[i]), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
r:=mrOk;
if hF1<>INVALID_HANDLE_VALUE then break;
r:=messagebox(handle,pchar("File access error"#13+lb1.items[i]+#13"What do you want to do?"),
"Error!",MB_ABORTRETRYIGNORE or MB_ICONERROR);
if r=mrIgnore then break else
if r=mrAbort then begin PostMessage(handle,WM_CLOSE,0,0); exit; end;
until 2=3;
if r<>mrOk then continue;
pb1.max:=getfilesize(hf1,@r);
Nofsl.Caption:=format("%d file from %d",[Curfile,Nofs]);
froml.Caption:="From: "+lb1.items[i];
if fnewal then
begin curdir:=(curdir mod length(dirnames))+1;
fn2:=ocopydir.path;
if fn2[length(fn2)]="\" then
fn2:=fn2+dirnames[curdir] else fn2:=fn2+"\"+dirnames[curdir];
CreateDirectory(pchar(fn2),nil);
fnewal:=false;
end;
fn2:=ocopydir.path;
if fn2[length(fn2)]="\" then
fn2:=fn2+dirnames[curdir]+"\"+Main.se2.lines[i] else fn2:=fn2+"\"+dirnames[curdir]+"\"+Main.se2.lines[i];
if not fileexists(fn2) then
try fst:=TFileStream.Create(fn2,fmCreate);
fst.Free;
except
end;
repeat
try
fst:=TFileStream.Create(fn2,fmOpenReadWrite or fmShareDenyWrite);
cc:=fst.Size;
fst.Position:=fst.Size;
setfilepointer(hf1,cc,nil,FILE_BEGIN);
r:=mrOk;
break;
except on Exception do
begin r:=messagebox(handle,pchar("File access error"#13+fn2+#13"What do you want to do?"),
"Error!",MB_ABORTRETRYIGNORE or MB_ICONERROR);
if r=mrIgnore then begin closehandle(hf1); break end
else if r=mrAbort then begin closehandle(hf1); PostMessage(handle,WM_CLOSE,0,0); exit; end;
end;
end;
until 2=3;
if r<>mrOk then continue;
Tol.Caption:="To: "+fn2;
application.ProcessMessages;
tc:=GetTickCount;
repeat
ReadFile(hf1,buf, 16384,r,nil);
repeat
if fst.Write(buf,r)=r then break;
r:=messagebox(handle,pchar("File write error"#13+fn2+#13"What do you want to do?"),
"Error!",MB_ABORTRETRYIGNORE or MB_ICONERROR);
if r=mrIgnore then begin r:=0; break end
else if r=mrAbort then begin fCancel:=true; break end;
until 2=3;
inc(cc,r);
if GetTickCount-tc>=1000 then
begin pb1.Position:=cc; FlushFileBuffers(fst.Handle); Application.ProcessMessages; tc:=GetTickCount; end;
until (r=0) or fCancel;
if not fCancel then lb1.Selected[i]:=false;
closehandle(hf1);
fst.Free;
inc(CurFile);
end;
if fCancel then
MessageBox(handle,pchar("Operation was cancelled"),"Warning",MB_OK or MB_ICONWARNING)
else MessageBox(handle,pchar("Operation comlete"),"Information",MB_OK or MB_ICONINFORMATION);
PostMessage(handle,WM_CLOSE,0,0);
end;
procedure TCopyf.CancelbClick(Sender: TObject);
begin
fCancel:=true;
end;
end.
← →
Reindeer Moss Eater (2003-01-24 08:30) [3]Никакого смысла в такой докачке нет.
Потому, что докачка одного недокачанного байта в файле размером 10 Мб займет столько же времени, сколько закачка всего 10 мегабайтного файла целиком.
← →
D.V.K (2003-01-24 16:41) [4]Не согласен. Я свою программу работающей видел.
нормально она докачивает.
Только вот с разрывом соединения проблемы.
← →
Reindeer Moss Eater (2003-01-24 16:43) [5]А я разве сказал, что не будет докачивать?
Я сказал, что ничего не сэкономишь на этом.
← →
Anatoly Podgoretsky (2003-01-24 16:48) [6]D.V.K (24.01.03 16:41)
Только вот с разрывом соединения проблемы.
С разрывом нет проблем, проще всего это осуществляется выдергиванием кабеля.
← →
Reindeer Moss Eater (2003-01-24 17:58) [7]Хотя неправ я. Можно экономить
← →
SeNtiMeL (2003-02-05 03:23) [8]Да очем вы ! Он же написал, что объемы будут большие, а скорость сети всего 10 МБ (а не размер файла 10 МБ).
Я проги типа Copy2File видел. Но работают они плохо. Т.к. с выключением ресурса, прога докачивает неправильно...
← →
_Narayan_ (2003-02-05 07:54) [9]Вот мой вариант, нужен исходник пиши на мыло.
Само копирование в отдельном потоке.
Здесь тока он.
unit U1Thread;
interface
uses SysUtils, Classes, ShellApi;
type
TLongCopyThread = class(TThread)
private
protected
procedure Execute; override;
end;
Type PointerOnData=^Integer;
Const SizeOfBuffer=64000;
cState_WaitingForChoice="
← →
Slym (2003-02-05 08:28) [10]Забавное сочетание WinAPI и компонент Delphi
Если ты читаешь файл на API зачем ты его пишешь TСтрёмом?
И вообще код коряв (неудобочитаем)
Для независания запихай сей код в поток
Страницы: 1 вся ветка
Текущий архив: 2003.03.27;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.009 c