2011-11-21 11 views
6

He escrito un programa que hace lo siguiente ...¿Hay alguna manera de hacer que mi programa delphi espere a que se copien una gran cantidad de archivos?

  • supervisa una carpeta para la creación de un nuevo archivo con un nombre de archivo específico que con el tiempo se crea en una carpeta secundaria.
  • Al crear el archivo, la ruta de las subcarpetas se agrega a una cola en forma de TList.
  • Los archivos deben procesarse en el orden de creación.
  • Se llama a un procedimiento para procesar todos los archivos (imágenes en este caso) en la subcarpeta que implica mover los archivos a una ubicación de red.
  • La ruta de la subcarpeta se elimina de la cola (TList).
  • Si existen más rutas en la cola, la siguiente ruta se pasa al procedimiento de procesamiento.

El problema que estoy teniendo es que el tiempo para copiar los archivos a una ubicación de red varía en función del número y tamaño de las imágenes así ...

¿Hay una manera de conseguir que esperar Delphi para el procedimiento de operación de archivo para terminar?

Intenté un bucle while que esperaba que cambiara un valor booleano (cambiado cuando se encontró el último archivo en la red) pero que colgó la aplicación (incluso con application.processMessage) y el componente dirMonitor no pudo agregue la siguiente subcarpeta a TList.

Cualquier sugerencia sería muy apreciada.

Gracias de antemano.


Gracias por las replys ...

yo tuvimos un vistazo a OmniThread que parece ideal ... a pesar de que sólo tienen acceso a Delphi 7 así que es un no ir.

El problema que tengo es que las carpetas tardan bastante tiempo en transferirse debido a diferentes tamaños, tráfico de red, etc. ... Cuando a una carpeta con muchas imágenes le sigue una carpeta con solo unas pocas imágenes, el el más pequeño de los dos está llegando primero al destino de la red. La red es una cola de impresión de terceros para que las impresiones salgan en el orden incorrecto.

El código simplificado:

procedure TForm1.programTimerTimer(Sender: TObject); 
begin 
    if (fileOperationInProgress = false) AND (programPaused = false) then 
    begin 
     processOrderQueue; 
    end; 
end; 

procedure TForm1.processOrderQueue; 
begin 
    // gets folder paths from queue 
    // processes images 
    // copy to print spooler (network location) 

    copyFolder(fromPath, toPath); 

    // remove temp files 
end; 

procedure TForm1.copyFolder(copyFrom : String; copyTo : String); 
var 
    fos : TSHFileOpStruct; 
begin 
    fileOperationInProgress := True; 

    ZeroMemory(@fos, SizeOf(fos)); 

    with fos do 
    begin 
     wFunc := FO_COPY; 
     fFlags := FOF_FILESONLY or FOF_SILENT; 
     pFrom := PChar(copyFrom); 
     pTo := PChar(copyTo) 
    end; 

    ShFileOperation(fos); 


    fileOperationInProgress := False; 
end; 

creo que he llegado con la respuesta ... Voy a hacer todas operationions de archivos en un solo hilo y establecer un mundial 'ocupado' boolean cuando comienza y lo cambia de nuevo al finalizar. De esta forma, el monitor de shell no perderá mensajes cuando las operaciones de archivos estén en progreso.

+3

¿Qué función está utilizando para copiar los archivos? [SHFileOperation] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164%28v=vs.85%29.aspx)? – RRUZ

+1

¿Cómo está copiando los archivos? Por favor muestra el código. –

+2

Podría intentar seguir el ejemplo de Gabr en [copy-file-in-a-thread] (http://stackoverflow.com/questions/1766626/copy-file-in-a-thread). El hilo principal se notifica cuando la copia termina. –

Respuesta

1

Puede implementar un reloj del sistema de archivos. En esencia, se crea un identificador de archivo con las siguientes banderas:

CreateFile(PChar(FDirectoryToWatch), FILE_LIST_DIRECTORY or GENERIC_READ, 
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, 
FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0); 

y luego crear un bucle para llamar ReadDirectoryChangesW.

vinculado es una clase de ejemplo: Why does ReadDirectoryChangesW omit events?

La única cosa que haría de manera diferente es ofrecer un evento en la creación de la clase para notificarle de cambios (recordando que cuando se llama al evento en el procedimiento que Ejecutar probablemente necesita ser sincronizado).

Cuestiones relacionadas