Czesc.
Twoj upor w dazeniu do celu zostal nagrodzony ;P Zrobie Ci gotowca jednakze chcialbym Ci takze pokazac jak winien przebiegac Twoj proces myslowy, moze to Ci ulatwi pisanie kodu w przyszlosci...
Wodzu napisał(a)
Sposob 2 (dokladnosc do bajtu):
Tak jak wczesniej, pobierasz sciezki do wszystkich plikow i zliczasz wielkosc kazdego pliku. Sumaryczna wielkosc wszystkich plikow = TProgressBar.Max. Reszte wykonujesz tak samo z tym ze inkrementujesz TProgressBar.Position o wielkosc ostatnio skopiowanego pliku. Proste ? ;)
Tutaj masz wszystko co potrzeba aby sobie zaimplementowac ten postep.
Wodzu napisał(a)
...zliczasz wielkosc kazdego pliku
Musimy znalezc metode na znalezienie wielkosci danego pliku. Moze cos z "file" i "size" bedzie w helpie Delphi? No patrz! Jest:
FileSize - Returns the current size of a file; not used for text files.
W dodatku Delphi 7 prawie od razu daje nam przyklad na kopiowanie pliku. To chyba nasz szczesliwy dzien ;).
var
FromF, ToF: file;
NumRead, NumWritten: Integer;
Buf: array[1..2048] of Char;
begin
if OpenDialog1.Execute then { Display Open dialog box }
begin
AssignFile(FromF, OpenDialog1.FileName);
Reset(FromF, 1); { Record size = 1 }
if SaveDialog1.Execute then { Display Save dialog box}
begin
AssignFile(ToF, SaveDialog1.FileName); { Open output file }
Rewrite(ToF, 1); { Record size = 1 }
repeat
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
BlockWrite(ToF, Buf, NumRead, NumWritten);
until (NumRead = 0) or (NumWritten <> NumRead);
CloseFile(FromF);
CloseFile(ToF);
end;
end;
Wystarczy do tego dodac dwie linie kodu aby miec postep kopiowania pliku. Ale pierwej przerobmy to na procedurke i ogarnijmy troche kod.
procedure CopyFileWithProgress(const AFrom, ATo: String; var AProgress: TProgressBar);
var
FromF, ToF: file;
NumRead, NumWritten, DataSize: Integer;
Buf: array[1..2048] of Char;
begin
DataSize := SizeOf(Buf);
AssignFile(FromF, AFrom);
Reset(FromF, 1);
AssignFile(ToF, ATo);
Rewrite(ToF, 1);
repeat
BlockRead(FromF, Buf, DataSize, NumRead);
BlockWrite(ToF, Buf, NumRead, NumWritten);
AProgress.Position := AProgress.Position + DataSize;
Application.ProcessMessages;
until (NumRead = 0) or (NumWritten <> NumRead);
CloseFile(FromF);
CloseFile(ToF);
end;
Jako parametr przekazujemy oprocz sciezek do plikow rowniez TProgressBar gdyz musimy zmieniac jego pozycje.
Mamy wiec kopiowanie jednego pliku z postepem operacji (gdy znamy wczesniej rozmiar tego pliku).
Teraz pora na skorzystanie z kolejnej wskazowki:
Wodzu napisał(a)
pobierasz sciezki do wszystkich plikow
Czesto walkowany temat na forum ale jak gotowiec to gotowiec ;) Pozwolilem sobie napisac funkcje przeszukujaca rekurencyjnie dany katalog i znajdujaca pliki do kopiowania. Wyglada ona tak:
procedure GatherFilesFromDirectory(const ADirectory: String;
var AFileList: TStringList; var ATotalSize: Int64);
var
SR: TSearchRec;
begin
if FindFirst(ADirectory + '\*.*', faDirectory, sr) = 0 then
begin
repeat
if ((SR.Attr and faDirectory) = SR.Attr) and (SR.Name <> '.') and (SR.Name <> '..') then
GatherFilesFromDirectory(ADirectory + '\' + Sr.Name, AFileList, ATotalSize);
until FindNext(SR) <> 0;
FindClose(SR);
end;
if FindFirst(ADirectory + '\*.*', 0, SR) = 0 then
begin
repeat
AFileList.Add(ADirectory + '\' + SR.Name);
Inc(ATotalSize, SR.Size);
until FindNext(SR) <> 0;
FindClose(SR);
end;
end;
ADirectory to folder startowy. AFileList to wskaznik na TStringList w ktorej trzymamy znalezione sciezki do plikow. Dodatkowo w ATotalSize mamy wielkosc w bajtach wszystkich znalezionych plikow, potrzebne do TProgressBar.Max.
No i w sumie gotowe. Mozna z tego skorzystac np tak:
procedure TfmMain.btCopyClick(Sender: TObject);
var
FileList: TStringList;
TotalSize: Int64;
i: Integer;
begin
TotalSize := 0;
FileList := TStringList.Create;
GatherFilesFromDirectory(edCopyFrom.Text, FileList, TotalSize);
pbProgress.Position := 0;
pbProgress.Max := TotalSize;
for i := 0 to FileList.Count - 1 do
begin
lbFile.Caption := 'Plik ' + FileList[i];
CopyFileWithProgress(FileList[i], edCopyTo.Text + ExtractFileName(FileList[i]), pbProgress);
end;
FileList.Free;
end;
Dodatkowo bedzie pokazywalo nazwe aktualnie kopiowanego pliku.
Pod tym linkiem znajdziesz program ze zrodlami:
http://www.speedyshare.com/527574196.html
Pozdrawiam
PS. Polecam ProgressBary z pakietu komponentow JEDI.