Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.49 MB
Время: 0.013 c
14-88138
Ru
2003-03-12 13:15
2003.03.27
Кучма :)


7-88257
Guru-ru
2003-01-30 15:43
2003.03.27
Как запустить удаленный компьютер


1-88019
DrFaust
2003-03-14 12:29
2003.03.27
Изменение размера формы


14-88202
alxx
2003-03-10 22:02
2003.03.27
Рисунки.


1-87968
arturik
2003-03-17 22:59
2003.03.27
Как найти в Delphi6 статистические функции?