Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.236.100.210] |
|
Сообщ.
#1
,
|
|
|
Тебе что, примеры нужны:
'in a form (Form1) Private Sub Form_Load() 'KPD-Team 2001 'URL: http://www.allapi.net/ 'E-Mail: KPDTeam@Allapi.net Dim Ret As Long 'set the graphics mode to persistent Me.AutoRedraw = True 'print some text Me.Print "Click the form to abort the filecopy" 'show the form Me.Show 'start copying Ret = CopyFileEx("c:\verybigfile.ext", "c:\copy.ext", AddressOf CopyProgressRoutine, ByVal 0&, bCancel, COPY_FILE_RESTARTABLE) 'show some text Me.Print "Filecopy completed " + IIf(Ret = 0, "(ERROR/ABORTED)", "successfully") End Sub Private Sub Form_Click() 'cancel filecopy bCancel = 1 End Sub 'in a module Public Const PROGRESS_CANCEL = 1 Public Const PROGRESS_CONTINUE = 0 Public Const PROGRESS_QUIET = 3 Public Const PROGRESS_STOP = 2 Public Const COPY_FILE_FAIL_IF_EXISTS = &H1 Public Const COPY_FILE_RESTARTABLE = &H2 Public Declare Function CopyFileEx Lib "kernel32.dll" Alias "CopyFileExA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal lpProgressRoutine As Long, lpData As Any, ByRef pbCancel As Long, ByVal dwCopyFlags As Long) As Long Public bCancel As Long Public Function CopyProgressRoutine(ByVal TotalFileSize As Currency, ByVal TotalBytesTransferred As Currency, ByVal StreamSize As Currency, ByVal StreamBytesTransferred As Currency, ByVal dwStreamNumber As Long, ByVal dwCallbackReason As Long, ByVal hSourceFile As Long, ByVal hDestinationFile As Long, ByVal lpData As Long) As Long 'adjust the caption Form1.Caption = CStr(Int((TotalBytesTransferred * 10000) / (TotalFileSize * 10000) * 100)) + "% complete..." 'allow user input DoEvents 'continue filecopy CopyProgressRoutine = PROGRESS_CONTINUE End Function Delphi doesn't supply a "CopyFile" routine, but you can just call the Windows API CopyFile function instead Here's an example - this one copies the file, even if the target file already exists. Note that file date, time and attributes are unchanged. If not CopyFile(PChar(SourceName),PChar(TargetName),False) then ShowMessage('Error copying file'); There are many other ways to copy a file (see the list below) but the one above is easiest and fastest (at least fastest of the ones I tested when I was looking for a high performing way to copy large files across a network). If you are copying a large file across a network, then you might like to show a progress bar - there are some good examples at the Swiss Delphi Centre at http://www.swissdelphicenter.ch/en/showcode.php?id=330 These routines mostly use BlockRead and write, so they don't perform as well as the basic Windows Copy function. If you are running on Windows NT, 2K or XP, then the best performing way that I was able to find to copy a file with a ProgressBar is to use the Windows CopyFileEx API call - see example at end. Hope this helps. Other examples from my (mostly very old) notes - I'm sure all of these can be improved - I was even more of a novice when I researched all these. COPYING FILES. How to copy files in Delphi - see Article #15910: Technical Information Database - plus my notes. I was testing over a 10 mbps LAN using relatively slow machines when these notes were written - a while back. 1. Method using a File stream. Note: Date/time of new file is now! Need extra code to preserve old date/time. No error handling; Delphi finds errors and writes an error box, cancelling the application, eg if the source file does not exist. Console applications just halt. Tested and works. Get c. 600-830 kB/sec over 10 Meg E'net. Average-750,000 Bytes/sec. Procedure FileCopy( Const SourceFn, TargetFn : String ); Var S, T: TFileStream; SourceHand, DestHand: Integer; Begin S := TFileStream.Create( SourceFn, fmOpenRead ); try T := TFileStream.Create( TargetFn, fmOpenWrite or fmCreate ); try T.CopyFrom(S, S.Size ) ; finally T.Free; end; finally S.Free; end; {Now set the new file's date/time to that of the source } SourceHand := FileOpen(SourceFn, fmOpenRead); { open source file } DestHand := FileOpen(TargetFn, fmOpenWrite); { open dest file } FileSetDate(DestHand, FileGetDate(SourceHand));{ get/set date } FileClose(SourceHand); { close source file } FileClose(DestHand); { close dest file } end; { Procedure FileCopy } 2. Method using memory blocks for read/write. Note: Brief test.. Does not preserve file time (as method 1.) Rate = c. 750 kB/sec Procedure FileCopy( Const SourceFn, TargetFn : String ); var FromF, ToF: file; NumRead, NumWritten: Integer; {Integer= 4 bytes.} Buf: array[1..2048] of Char; begin AssignFile(FromF, SourceFn); Reset(FromF, 1);{ Record size = 1 } AssignFile(ToF, TargetFn);{ 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; 3. Method using LZCopy. (Must specify Uses LZExpand Date/time preserved. } Note: Time error when copying from WinNT to Win95. Must use code from example 1 to correct the time of the target. Procedure FileCopy( Const SourceFn, TargetFn : String ); Note: This code did not run on WinXP??? - Oct03. var FromFile, ToFile: File; begin AssignFile(FromFile, SourceFn); { Assign FromFile to SourceFn } AssignFile(ToFile, TargetFn); { Assign ToFile to TargetFn } Reset(FromFile); { Open file for input } try Rewrite(ToFile); { Create file for output } try { copy the file and if a negative value is returned raise an exception } if LZCopy(TFileRec(FromFile).Handle, TFileRec(ToFile).Handle) < 0 then raise EInOutError.Create('Error using LZCopy') finally CloseFile(ToFile); { Close ToFile } end; finally CloseFile(FromFile); { Close FromFile } end; end; {-------------- Procedure FileCopy -----------------------------} 4. Example with ProgressBar. (I get up to 11MBytes/sec with this routine across a 100 Mbps Ethernet). This example uses Windows COPYFILEEX. This copies with a progressbar. It works fine and is the fastest yet with progressbar. I adapted this one from some code I found on a French Delphi Web site at http://www.delphifr.com/code.aspx?ID=12315 - many thanks to Nicolas Sorel. Translation is mine! ---------------------------------------------------------------------------- ---} Function CopyCallBack( TotalFileSize: LARGE_INTEGER; // Total size of the file in bytes TotalBytesTransferred: LARGE_INTEGER; // No bytes already transferred. StreamSize: LARGE_INTEGER; // Total file size StreamBytesTransferred: LARGE_INTEGER; // No bytes already transferred dwStreamNumber: DWord; // Number of the stream dwCallbackReason: DWord; // Reason for the call back. hSourceFile: THandle; // Source handle. hDestinationFile: THandle; // Destination handle. ProgressBar : TProgressBar // Parameter passed to the function which is // a recopy of the parameter passed with // CopyFileEx. It is used to pass the address // of progress bar to be updated for the copy. // It is an excellent idea of DelphiProg. ): DWord; far; stdcall; var EnCours: Int64; begin // Calculate progressbar position as a percent. The calculation must be // performed using an intermediate variable of type Int64, to avoid overflow // of calculation in the property Position of the integer type. // BB Note - look up LARGE_INTEGER to see what Quadpart is. EnCours := TotalBytesTransferred.QuadPart*100 div TotalFileSize.QuadPart; if ProgressBar<>Nil then ProgressBar.Position := EnCours; // The function must determine whether the copy can be continued. Result := PROGRESS_CONTINUE; Application.ProcessMessages; // Allow processing of messages. end; {---Function FILECOPY: New Version (Nov03) using CopyFileEx.----------} { If BAR is true a progressbar is shown. } Function FileCopy(Const SourceFn, TargetFn : String; Bar : Boolean ): Boolean; Var I : Integer; Retour: LongBool; begin Result:=True; // Default result - copy OK. If (Win32Platform = Ver_Platform_Win32_NT) and Bar then begin { BAR wanted - but only possible on WinNT, 2000 or XP } Form1.ProgressBar1.Visible:=True; // Show progressbar only during copy. Retour := False; // NB CopyFileEx only works on WinNT,2k or XP.} if not CopyFileEx( PChar(SourceFn), // Source file name PChar(TargetFn), // Target file name. @CopyCallBack, // Address of callback function Form1.ProgressBar1, // ProgressBar to be updated. @Retour, // Address of Boolean tested to stop the copy // Don't specify "can be restarted" or "only if not exists" then Result:=False; end else begin ---code to perform copy without progressbar.--- end; end; {---Procedure FileCopy-----} + http://www.delphifr.com/code.aspx?ID=12315 Эта тема была разделена из темы "Копирование, удаление файлов и папок" |
Сообщ.
#2
,
|
|
|
M Тема перенесена из Delphi FAQ -> Системные функции, WinAPI, работа с железом |