Jak skopiować plik do końca
warlock
Jak skopiować plik do końca?
Potrzeba nam do tego plik ,który nie skopiował się do końca :).
<font size="5">Delphi 7</span>
Żeby to było w miarę możliwe i wygodne napisałem klasę pochodną od TFileStream ,która uzupełnia ją o jedną funkcję - CopyRest.
{-=================-}
{| [email protected] |}
{-=================-}
unit CopyRest;
interface
uses
Classes;
type
TCRFileStream = class(TFileStream)
public
function CopyRest(Source: TStream): Int64;
end;
implementation
function TCRFileStream.CopyRest(Source: TStream): Int64; //funkcja zwraca wartość przedstawiającą ilość zapisanych bajtów
const
MaxBufSize = $F000; // Maksymalny rozmiar buforu. Dla przejżystości napiszę ,że w systemie dziesiętnym jest równy 61440
var
BufSize, N: Integer;
Buffer: PChar;
Pos: Int64;
begin
Pos := source.Size - Size;
Source.Seek(Pos*-1,soFromEnd);
Seek(0,soFromEnd);
Result := Pos;
if Pos > MaxBufSize then BufSize := MaxBufSize else BufSize := Pos;
GetMem(Buffer, BufSize);
try
while Pos <> 0 do
begin
if Pos > BufSize then N := BufSize else N := Pos;
Source.ReadBuffer(Buffer^, N);
WriteBuffer(Buffer^, N);
Dec(Pos,N);
end;
finally
FreeMem(Buffer, BufSize);
end;
end;
end.
A teraz mały przykład:
procedure TForm1.Button1Click(Sender: TObject);
var
Read, Write : TCRFileStream;
plik1, plik2 : TFileName;
begin
plik1 := 'C:\1.txt'; //zkąd
plik2 := 'C:\folder\1.txt'; //dokąd
try
Read := TCRFileStream.Create(plik1,fmOpenRead or fmShareDenyNone);
if FileExists(plik2) then // jeszcze lepiej by było sprawdzić po bitach w pliku, ale to już pozostawiam wam!
begin
try
Write := TCRFileStream.Create(plik2,fmOpenWrite);
Write.CopyRest(Read);
finally
Write.Free;
end;
end
else
begin
try
Write := TCRFileStream.Create(plik2,fmCreate);
Write.CopyFrom(Read,0);
finally
Write.Free;
end;
end;
finally
Read.Free;
end;
end;
Oczywiście ten przykład w pełni nie wykorzystuje wszystkich możliwości :).
Aby przykład działał poprawnie ,plik CopyRest.pas należy umieścić w katalogu z kodem programu oraz w deklaracjach uses dodać CopyRest.
<font size="5">Delphi 8 .NET</span>
W Delphi 8 .NET niepotrzebne jest stworzenie jakiejkolwiek klasy.
unit WinForm1;
interface
uses
System.Drawing, System.Collections, System.ComponentModel,
System.Windows.Forms, System.Data, System.Configuration, System.Resources, System.IO, System.Threading;
type
TWinForm1 = class(System.Windows.Forms.Form)
{$REGION 'Designer Managed Code'}
strict private
{....}
{$ENDREGION}
strict protected
/// <summary>
/// Clean up any resources being used.
/// </summary>
procedure Dispose(Disposing: Boolean); override;
private
{ Private Declarations }
public
CopyFrom, CopyTo : string;
t : Thread;
constructor Create;
procedure Kopiuj;
end;
[assembly: RuntimeRequiredAttribute(TypeOf(TWinForm1))]
implementation
{...}
procedure TWinForm1.Kopiuj;
var
i : integer;
FsFrom, FsTo : FileStream;
BrFrom : BinaryReader;
BrTo : BinaryWriter;
BufferL : Integer;
begin
Button2.Enabled := false;
BufferL := 6144;
FsFrom := FileStream.Create(CopyFrom, FileMode.Open, FileAccess.Read, FileShare.Read);
FsTo := FileStream.Create(CopyTo,FileMode.Append);
FsFrom.Position := FsTo.Length;
ProgressBar1.Maximum := FsFrom.Length;
ProgressBar1.Value := FsTo.Length;
BrFrom := BinaryReader.Create(FsFrom);
BrTo := BinaryWriter.Create(FsTo);
while FsFrom.Length <> FsTo.Position do
begin
if (FsFrom.Length - FsFrom.Position) < BufferL then
BufferL := FsFrom.Length - FsFrom.Position;
BrTo.Write(BrFrom.ReadBytes(BufferL));
ProgressBar1.Value := ProgressBar1.Value + BufferL;
end;
Button2.Enabled := true;
end;
procedure TWinForm1.TWinForm1_Closed(sender: System.Object; e: System.EventArgs);
begin
if t <> nil then
t.Abort;
end;
procedure TWinForm1.Button2_Click(sender: System.Object; e: System.EventArgs);
begin
if (OpenFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK) then
CopyFrom := OpenFileDialog1.FileName;
if (SaveFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK) then
CopyTo := SaveFileDialog1.FileName;
t := Thread.Create(Kopiuj);
t.Start;
end;
Pozdrawiam!
;)
;) fajnie jakby to jeszcze działało tak jak to opisuje autor ;) :)
To może ocena co!?
Program z wykorzystaniem tego kodu i z kodem źródłowym znajduje się na:
http://members.lycos.co.uk/totalclone/
To w takim razie przyda się, nawet bardzo :)
Z tym "do końca" chodzi Ci o to, że np. plik nie został skopiowany z powodu błędów odczytu z miejsca źródłowego etc. czy masz może inne pojęcie "końców"? :) Wiem, że jestem CKM :)
Tak jak piszesz! Przerwane kopiowanie - reset kompa itp.