Thema: Delphi FileExistsWait

Einzelnen Beitrag anzeigen

musicman56
(Gast)

n/a Beiträge
 
#6

AW: FileExistsWait

  Alt 17. Jan 2013, 15:34
Hallo,

wenn es darum geht sicherzustellen, dass eine Kopiervorgang abgeschlossen ist, verwende ich meine eigene kleine Kopier-Routine:

Delphi-Quellcode:
type
  TFileOverwriteMode = (fomAlways, fomIfNewer, fomIfOlder, fomIfSameDate);
  TFileCopyCallback = procedure(ProgressValue: int64) of object;

function RF_SetAllFileDates(FName: string;
                            aCreation,
                            aLastAccess,
                            aLastWrite : TDateTime): boolean;
var
  aHandle: integer;
  FT1, FT2, FT3: TFileTime;
  locFT1, locFT2, locFT3: TFileTime;
  ST1, ST2, ST3 : TSystemTime;
begin
  aHandle := FileOpen(FName, fmOpenWrite or fmShareDenyWrite);
  Result := aHandle >= 0;

  if Result then
  try
    DateTimeToSystemTime(aCreation,ST1);
    DateTimeToSystemTime(aLastAccess,ST2);
    DateTimeToSystemTime(aLastWrite,ST3);

    SystemTimeToFileTime(ST1,FT1);
    SystemTimeToFileTime(ST2,FT2);
    SystemTimeToFileTime(ST3,FT3);

    LocalFileTimeToFileTime(FT1,locFT1);
    LocalFileTimeToFileTime(FT2,locFT2);
    LocalFileTimeToFileTime(FT3,locFT3);

    SetFileTime(aHandle,@locFT1, @locFT2, @locFT3);
  finally
    FileClose(aHandle);
  end;
end;

function RF_CopyFile(SourceName, DestName: string;
                     CopyMode: TFileOverwriteMode;
                     Progress: TFileCopyCallback): boolean;
var
  BytesRead,BytesToRead, P, Percent: Int64;
  SourceStream, DestStream: TFileStream;
  SourceDateTime, DestDateTime: TDateTime;
  Execute: boolean;
begin
  Result := false;
  if not FileExists(SourceName) then exit;
  if not FileAge(SourceName, SourceDateTime) then exit;
  Execute:= true;
  BytesRead := 0;
  Percent := 0;
  P := 0;
  {-DestName darf auch ein Directory sein...dann den Dateinamen ran hängen}
  if DirectoryExists(DestName)
  then DestName := IncludeTrailingBackslash(DestName)+ExtractFileName(SourceName);
  if FileExists(DestName) then begin
    if not FileAge(DestName, DestDateTime) then exit;
    case CopyMode of
      fomAlways : ;
      fomIfNewer : Execute := DestDateTime > SourceDateTime;
      fomIfOlder : Execute := DestDateTime < SourceDateTime;
      fomIfSameDate : Execute := Trunc(DestDateTime) = Trunc(SourceDateTime);
    end;
  end;
  if not Execute then exit;
  SourceStream := TFileStream.Create(SourceName,fmOpenRead or fmShareDenyNone);
  DestStream := TFileStream.Create(DestName,fmCreate);
  try
    if @Progress = nil then begin // so geht es am schnellsten
      DestStream.CopyFrom(SourceStream,SourceStream.Size);
      Result := true; // was soll noch schiefgehen ??
    end else begin // mit Fortschrittanzeige
      Progress(Percent);
      BytesToRead := SizeOf(StreamCopyBuffer);
      if SourceStream.Size < BytesToRead then BytesToRead := SourceStream.Size;
      repeat
        SourceStream.ReadBuffer(StreamCopyBuffer,BytesToRead);
        DestStream.WriteBuffer(StreamCopyBuffer,BytesToRead);
        BytesRead := BytesRead + BytesToRead;
        Percent := (BytesRead * 100) div SourceStream.Size;
        if P <> Percent then begin
          Progress(Percent);
          P := Percent;
        end;
        if (SourceStream.Size - BytesRead) <= BytesToRead
        then BytesToRead := SourceStream.Size - BytesRead;
      until BytesRead >= SourceStream.Size;
      Result := BytesRead = SourceStream.SIZE;
    end;
  finally
    SourceStream.Free;
    DestStream.Free;
  end;
  if Result then RF_SetAllFileDates(DestName, SourceDateTime, SourceDateTime, SourceDateTime);
end;
So nebenbei hab ich eine bessere Kontrolle was mit einer vorhandenen Datei passieren soll.
  Mit Zitat antworten Zitat