2011-07-31 9 views
7

Mi programa de Windows recibe información de otro programa a través de la interfaz de directorio/archivo. Ese es el otro programa que suelta archivos en un directorio especial. Mi programa escanea periódicamente el directorio, encuentra los archivos, los procesa y luego los elimina.Eliminar un archivo abierto para acceso exclusivo en el mismo proceso

Utilizo la función CreateFile() para abrir dichos archivos. Para garantizar que el otro programa haya terminado de escribir en el archivo y lo haya cerrado, configuré el parámetro dwShareMode en 0. Si CreateFile falla con un error de uso compartido, salte el archivo hasta la siguiente iteración.

El problema es que DeleteFile() falla con el error ERROR_SHARING_VIOLATION mientras que el archivo se abre en mi programa.

pude cerrar el archivo antes de deleteing, pero me gustaría evitar la posibilidad de algún otro programa de abrir el archivo justo antes de borrar el archivo.

que utiliza este código para abrir archivos

CreateFile(filePath,DELETE|FILE_READ_DATA,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL) 

¿Es posible lograr lo que quiero: abrir el archivo exclusivamente un borrarla, por lo que ningún otro programa puede interferir entre openning y deleteting el archivo.

Respuesta

3

Pase en FILE_SHARE_DELETE para dwShareMode. Tenga en cuenta que esto permitirá que otras aplicaciones (además del suyo) llamen al DeleteFile() mientras está leyendo el archivo, pero de acuerdo con la documentación de DeleteFile() no se eliminará hasta que no llame a CloseHandle() para cerrar su lectura encargarse de.

La función DeleteFile marca un archivo para eliminar al cerrar. Por lo tanto, , la eliminación del archivo no se produce hasta que se cierra el último identificador del archivo . Las llamadas posteriores a CreateFile para abrir el archivo fallan con ERROR_ACCESS_DENIED.

Otras aplicaciones no serán capaces de leer o escribir el archivo, siempre y cuando no se especifica FILE_SHARE_READ o FILE_SHARE_WRITE respectivamente. Aunque con FILE_SHARE_DELETE puede mover el archivo, pero eso sería todo.

6

FILE_FLAG_DELETE_ON_CLOSE es probablemente lo que está buscando. De MSDN

* FILE_FLAG_DELETE_ON_CLOSE 0x04000000 - El archivo se va a eliminar de inmediato después de que todos sus asas están cerrados, que incluye el identificador especificado y cualquier otro identificadores abiertos o duplicados. Si existen controladores abiertos para un archivo, la llamada falla a menos que todos se hayan abierto con el modo de compartir FILE_SHARE_DELETE. solicitudes subsiguientes para abrir el archivo fallan, a menos que se especifique el modo compartido FILE_SHARE_DELETE *

EDIT:. Agregado un ejemplo ...

Por lo tanto, en caso de que usted debe:

HANDLE hFile = ::CreateFile(filePath, 
       DELETE|FILE_READ_DATA, 
       0, 
       NULL, 
       OPEN_EXISTING, 
       FILE_FLAG_DELETE_ON_CLOSE, 
       NULL); 

//use the file... 

::CloseHandle(hFile); //the file gets deleted when the handle is closed 
Cuestiones relacionadas