📄 unittransfer.pas
字号:
unit UnitTransfer;
interface
uses windows, SysUtils, Dialogs, ComCtrls, IdTCPServer, UnitFunciones;
type TCallbackProcedure = procedure(Sender: Tobject) of object;
type
TDescargaHandler = class(TObject)
public
ProgressBar: TProgressBar;
ListView: TListView;
AThread: TIdPeerThread;
Item: TListItem;
Descargado: Int64;
SizeFile: Int64;
ultimoBajado: int64;
Origen, Destino: AnsiString;
Transfering: boolean;
Finalizado: boolean;
Status: string;
cancelado: boolean;
callback: TCallbackProcedure;
es_descarga: boolean;
constructor Create(PThread: TIdPeerThread; fname: AnsiString; TSize: integer; PDownloadPath: AnsiString; pListView: TListView; p_es_descarga: boolean); overload;
procedure addToView;
procedure TransferFile;
procedure ResumeTransfer;
procedure CancelarDescarga;
procedure UploadFile;
procedure Update;
procedure UpdateVelocidad;
private
end;
implementation
constructor TDescargaHandler.Create(PThread: TIdPeerThread; fname: AnsiString; TSize: integer; PDownloadPath: AnsiString; pListView: TListView; p_es_descarga: boolean);
begin
Athread := pThread;
Origen := fname;
Destino := pDownloadPath;
SizeFile := TSize;
ListView := pListView;
transfering := false;
cancelado := false;
finalizado := false;
es_descarga := p_es_descarga;
ProgressBar := TProgressBar.Create(nil);
ProgressBar.Max := TSize;
if Athread <> nil then
AThread.Synchronize(self.addToView)
else
self.addToView;
end;
procedure TDescargaHandler.addToView;
var
RectProg: TRect;
begin
item := ListView.items.add;
item.Caption := ExtractFileName(Origen);
Item.SubItems.Add('Waiting');
Item.SubItems.Add(ObtenerMejorUnidad(self.SizeFile));
Item.SubItems.Add('0 Kb');
Item.SubItems.Add('');
Item.SubItems.Add('Waiting');
if es_descarga then Item.ImageIndex := 38
else Item.ImageIndex := 36;
Item.Data := self;
RectProg := Item.DisplayRect(drBounds);
RectProg.Left := RectProg.Left + ListView.Columns[0].Width;
RectProg.Right := RectProg.Left + ListView.Columns[1].Width;
ProgressBar.BoundsRect := RectProg;
progressBar.Parent := ListView;
end;
procedure TDescargaHandler.TransferFile;
var
Buffer: array[0..1023] of Byte;
F: file;
read, currRead: integer;
tickBefore, tickNow: integer;
seconds: extended;
buffSize: integer;
begin
transfering := true;
status := 'Downloading';
AssignFile(F, Destino);
Rewrite(F, 1);
read := 0;
currRead := 0;
tickBefore := getTickCount;
tickNow := getTickCount;
UltimoBajado := 0;
buffSize := SizeOf(Buffer);
try
while ((read < SizeFile) and Athread.Connection.Connected and not cancelado) do
begin
if (SizeFile - read) >= buffSize then
currRead := buffSize
else
currRead := (SizeFile - read);
Athread.Connection.ReadBuffer(buffer, currRead);
read := read + currRead;
tickNow := getTickCount;
if (tickNow - TickBefore >= 1000) then
begin
Athread.Synchronize(UpdateVelocidad);
tickBefore := tickNow;
UltimoBajado := Descargado;
end;
BlockWrite(F, Buffer, currRead);
currRead := 0;
Descargado := read;
Athread.Synchronize(Update);
end;
finally
CloseFile(F);
Athread.Data := nil;
Athread.Connection.Disconnect;
seconds := (gettickcount - tickBefore) / 1000;
transfering := false;
if read <> SizeFile then
begin
status := 'Stopped';
cancelado := true;
Transfering := false;
end
else
begin
status := 'Done';
finalizado := true;
transfering := false;
end;
Athread.Synchronize(Update);
if @callback <> nil then
callback(self);
end;
end;
procedure TDescargaHandler.ResumeTransfer;
var
Buffer: array[0..1024] of Byte;
F: file;
read, currRead: integer;
tickBefore, tickNow: integer;
seconds: extended;
buffSize: integer;
begin
transfering := true;
cancelado := false;
status := 'Downloading';
tickBefore := getTickCount;
if FileExists(destino) then
begin
AssignFile(F, Destino);
reset(F, 1);
end
else
begin
AssignFile(F, Destino);
Rewrite(F, 1);
end;
seek(f, Descargado);
read := Descargado;
currRead := 0;
tickBefore := getTickCount;
tickNow := getTickCount;
UltimoBajado := 0;
buffSize := SizeOf(Buffer);
try
while ((read < SizeFile) and Athread.Connection.Connected and not cancelado) do
begin
if (SizeFile - read) >= buffSize then
currRead := buffSize
else
currRead := (SizeFile - read);
Athread.Connection.ReadBuffer(buffer, currRead);
read := read + currRead;
tickNow := getTickCount;
if (tickNow - TickBefore >= 1000) then
begin
Athread.Synchronize(UpdateVelocidad);
tickBefore := tickNow;
UltimoBajado := Descargado;
end;
BlockWrite(F, Buffer, currRead);
Descargado := read;
Athread.Synchronize(Update);
end;
finally
CloseFile(F);
Athread.Data := nil;
Athread.Connection.Disconnect;
seconds := (gettickcount - tickBefore) / 1000;
transfering := false;
if read <> SizeFile then
begin
status := 'Stopped';
cancelado := true;
Transfering := false;
end
else
begin
status := 'Done';
finalizado := true;
transfering := false;
end;
Athread.Synchronize(Update);
if @callback <> nil then
callback(self);
end;
end;
procedure TDescargaHandler.UploadFile;
var
myFile: file;
byteArray: array[0..1023] of byte;
count, sent, filesize: integer;
tickBefore, tickNow: integer;
begin
filesize := GetFileSize(Origen);
if not filesize > 0 then
begin
MessageDlg('Cant access to file, maybe it is in use', mtWarning, [mbok], 0);
AThread.Connection.Disconnect;
Exit;
end;
transfering := true;
cancelado := false;
status := 'Uploading';
try
FileMode := $0000;
AssignFile(myFile, Origen);
reset(MyFile, 1);
sent := 0;
tickBefore := getTickCount;
UltimoBajado := 0;
while not EOF(MyFile) and AThread.Connection.Connected and not cancelado do
begin
BlockRead(myFile, bytearray, 1024, count);
sent := sent + AThread.Connection.Socket.Send(bytearray, count);
tickNow := getTickCount;
if (tickNow - TickBefore >= 1000) then
begin
Athread.Synchronize(UpdateVelocidad);
tickBefore := tickNow;
UltimoBajado := Descargado;
end;
Descargado := sent;
Athread.Synchronize(Update);
end;
finally
closefile(myfile);
if sent <> filesize then
begin
cancelado := true;
transfering := false;
finalizado := false;
Status := 'Stopped';
end
else
begin
cancelado := false;
transfering := false;
finalizado := true;
Status := 'Done';
end;
Athread.Synchronize(Update);
end;
end;
procedure TDescargaHandler.CancelarDescarga;
begin
cancelado := true;
transfering := false;
Finalizado := false;
end;
procedure TDescargaHandler.Update;
begin
ProgressBar.Position := self.Descargado;
if Item.SubItems[4] <> Status then Item.SubItems[4] := Status;
Item.SubItems[2] := ObtenerMejorUnidad(Descargado);
end;
procedure TDescargaHandler.UpdateVelocidad;
begin
Item.SubItems[3] := ObtenerMejorUnidad(Descargado - UltimoBajado) + '/s';
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -