Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2003.03.27;
Скачать: [xml.tar.bz2];

Вниз

Как возобновить копирование файла после падения локальной сети   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.011 c
1-88022
malkolinge
2003-03-14 13:06
2003.03.27
Эмуляция мыши


3-87809
ArtyomW
2003-03-07 23:47
2003.03.27
Сортировка полей


1-87950
revo
2003-03-17 17:35
2003.03.27
Распознавание голоса


7-88264
Adolf
2003-02-01 17:53
2003.03.27
Restart


1-88009
---cev---
2003-03-14 10:40
2003.03.27
Поиск строки в текстовом файле





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский