Copiar un fichero
Artículo por Club Developers · 31 diciembre 2005
3336 vistas
Podemos usar la función ShFileOperation que permite, entre otras cosas, la copia de ficheros. En caso de error, el sistema mostrará un cuadro de diálogo indicando la causa del error. Los flags FOF_xxx configuran la operación (consultar la ayuda en linea para más información).
Controlando los errores
No obstante, si queremos controlar los mensajes de error de la copia, tendremos que usar la función CopyFile(NombreFicheroInicial, NombreFicheroFinal: String; Control: boolean): boolean;
El parámetro "Control" indica cómo actuar en caso de que el fichero exista:
Con barra de progreso
A veces, también puede ser interesante el mostrar una barra de progreso mientras se copia un fichero. Si usamos una función de alto nivel como CopyFile, nos simplificaremos mucho la vida, pero no podremos usar nuestra barra de progreso...
La solución que proponemos es la siguiente:
Paso 1: Abrir el fichero Origen y crear el Destino
Paso 2: Leer un bloque de datos del fichero Origen
Paso 3: Actualizar la barra de progreso
Paso 4: Grabar el bloque leido en el fichero Destino
Paso 5: Si no se ha copiado todo el fichero, volver al paso 2.
Un ejemplo:
Este ejmplo usa un buffer de 2048 bytes. Cuando mayor sea el buffer, más velocidad daremos a la rutina.
Nota: se recomienda hacer controles estilo a mirar si el fichero existe, mirar si hay suficiente espacio en disco, comprobar si el destino existe y, en caso afirmativo preguntar qué hacer,....
delphi
function CopyFile(Source, Destination: String): boolean; var fos: TSHFileOpStruct; begin FillChar(fos, SizeOf(fos),0); with fos do begin wFunc := FO_COPY; pFrom := PChar(Source+#0); pTo := PChar(Destination+#0); fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT; end; result := (0 = ShFileOperation(fos)); end;
Controlando los errores
No obstante, si queremos controlar los mensajes de error de la copia, tendremos que usar la función CopyFile(NombreFicheroInicial, NombreFicheroFinal: String; Control: boolean): boolean;
El parámetro "Control" indica cómo actuar en caso de que el fichero exista:
- Si es true, no hará la copia y la función devolverá false
- Si es false, reemplazará el fichero existente y la función devolverá true
Con barra de progreso
A veces, también puede ser interesante el mostrar una barra de progreso mientras se copia un fichero. Si usamos una función de alto nivel como CopyFile, nos simplificaremos mucho la vida, pero no podremos usar nuestra barra de progreso...
La solución que proponemos es la siguiente:
Paso 1: Abrir el fichero Origen y crear el Destino
Paso 2: Leer un bloque de datos del fichero Origen
Paso 3: Actualizar la barra de progreso
Paso 4: Grabar el bloque leido en el fichero Destino
Paso 5: Si no se ha copiado todo el fichero, volver al paso 2.
Un ejemplo:
delphi
procedure TForm1.Button1Click(Sender: TObject); var Origen, Destino :file of byte; Buffer :array[0..4096] of char; Leidos :integer; Longitud :longint; begin { Abrimos fichero Origen y Destino } AssignFile(Origen,'c:\MiArchivoOrigen.txt'); reset(Origen); AssignFile(Destino,'c:\MiArchivoDestino.txt'); rewrite(Destino); { Hallamos la longitud del fichero a copiar } Longitud := FileSize(Origen); { Actualizamos limites de la ProgressBar } ProgressBar1.Max := Longitud; ProgressBar1.Min := 0; while Longitud > 0 do begin BlockRead(Origen, Buffer[0], SizeOf(Buffer), Leidos); Longitud := Longitud - Leidos; BlockWrite(Destino, Buffer[0], Leidos); ProgressBar1.Position := ProgressBar1.Position + Leidos; end; CloseFile(Origen); CloseFile(Destino); end;
Este ejmplo usa un buffer de 2048 bytes. Cuando mayor sea el buffer, más velocidad daremos a la rutina.
Nota: se recomienda hacer controles estilo a mirar si el fichero existe, mirar si hay suficiente espacio en disco, comprobar si el destino existe y, en caso afirmativo preguntar qué hacer,....