第六章-文件管理(三)(2)2007-05-076.4.5.2 文件拷贝、移动、删除、更名 文件拷贝的关键是使用了以文件句柄为操作对象的文件管理函数,因而提供了一种底层的I/O通道。在Object Pascal中这一点是利用无类型文件实现的。在文件拷贝中首先检查目标文件名是否是一个目录。如是则把原文件的文件名添加到目标路径后,生成目标文件全路径名。而后提取源文件的时间戳,以备拷贝完成后设置目标文件。拷贝过程中使用了返回文件句柄或以文件句柄为参数的文件管理函数FileOpen、FileCreate、FileRead、FileWrite、FileClose。为保证文件的正常关闭和内存的释放,在拷贝过程中进行异常保护。过程CopyFile实现上述功能,它定义在fmxutils单元中。 procedure CopyFile(const FileName, DestName: TFileName);varCopyBuffer: Pointer; TimeStamp, BytesCopied: Longint;Source, Dest: Integer; Destination: TFileName; constChunkSize: Longint = 8192; beginDestination := ExpandFileName(DestName); if HasAttr(Destination, faDirectory) then Destination := Destination + "" + ExtractFileName(FileName); TimeStamp := FileAge(FileName); GetMem(CopyBuffer, ChunkSize); trySource := FileOpen(FileName, fmShareDenyWrite);if Source < 0 then raise EFOpenError.Create(FmtLoadStr(SFOpenError, [FileName]));tryDest := FileCreate(Destination); if Dest < 0 then raise EFCreateError.Create(FmtLoadStr(SFCreateError,[Destination]));tryrepeatBytesCopied := FileRead(Source, CopyBuffer^, ChunkSize); if BytesCopied > 0 then FileWrite(Dest, CopyBuffer^, BytesCopied); until BytesCopied < ChunkSize; finallyFileSetDate(Dest,TimeStamp);FileClose(Dest); end;finallyFileClose(Source); end;finallyFreeMem(CopyBuffer, ChunkSize);end;end;如果我们不使用FileSetDate过程,Windows自动把当前时间作为时间戳写入文件。文件移动事实上是文件拷贝与文件删除的结合。fmxutils单元中的MoveFile过程实现了这一功能。 procedure MoveFile(const FileName, DestName: TFileName);varDestination: TFileName;beginDestination := ExpandFileName(DestName); if not RenameFile(FileName, Destination) then beginif HasAttr(FileName, faReadOnly) then raise EFCantMove.Create(Format(SFCantMove, [FileName])); CopyFile(FileName, Destination); DeleteFile(FileName); end;end; EFCanMove是一个自定义异常类: typeEFCanMove := Class(EStreamError);有关自定义异常类请参阅第十二章。文件删除、文件更名直接调用Delphi文件管理过程DeleteFile、RenameFile。它们都以文件名为参数。操作执行前应弹出一个对话框进行确认,执行完毕后应调用Update方法更新FileList的显示。