Esperar hasta que un archivo esté disponible para leer con Win32

 C Programming >> Programación C >  >> Tags >> File
Esperar hasta que un archivo esté disponible para leer con Win32

No creo que haya una notificación para el tipo de evento que estás buscando, pero como mejora, sugeriría retrasos progresivos. De esta manera, obtendrá tiempos de respuesta rápidos para cosas como arrastrar y soltar y no acaparará la CPU con un ciclo cerrado si el usuario mantiene el archivo abierto durante una hora en Excel.

int delay= 10;
while ((hFile = CreateFile (path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
{
    if (GetLastError() == ERROR_SHARING_VIOLATION) {
        Sleep (delay);
        if (delay<5120) // max delay approx 5.Sec
            delay*= 2;
    }
    else
        break; // some other error occurred
}

No hay API de modo de usuario para notificaciones en un archivo cerrado que yo sepa. El ciclo que ha propuesto es probablemente la mejor manera. La única otra cosa que podrías hacer sería estar atento a CloseFile en un controlador de filtro ala Process Monitor, pero qué asco...


Como dijo @Matt Davis, lamentablemente no existe una API de modo de usuario, pero existe una solución alternativa que, según su caso de uso (he escrito el mío a continuación), puede hacer exactamente lo que desea.

Lo que funcionó para mí en el pasado fue registrarme para FILE_NOTIFY_CHANGE_LAST_WRITE en lugar de FILE_NOTIFY_CHANGE_FILE_NAME al llamar ReadDirectoryChangesW :

ZeroMemory(&overlapped, sizeof(OVERLAPPED));
overlapped.hEvent = hChangeEvent;

// ...    
ReadDirectoryChangesW(hSpoolPath,
                      eventBuffer,
                      EVENT_BUF_LENGTH,
                      FALSE,
                      FILE_NOTIFY_CHANGE_LAST_WRITE, // <----
                      NULL,
                      &overlapped,
                      NULL);
// ...
HANDLE events[2];

events[0] = hChangeEvent;
events[1] = hCancelEvent;

DWORD wRc = WaitForMultipleObjects(2, events, FALSE, DIRECTORY_WATCH_TIMEOUT);

La última hora de escritura se actualiza tan pronto como el proceso propietario cierra el identificador después de crear el archivo y escribir en él.

Mi caso de uso fue un proceso que recibió solicitudes HTTP a través de TCP/IP y escribió el cuerpo HTTP en un directorio, donde otro proceso lo recogió tan pronto como el proceso de recepción terminó de escribirlo (y, en consecuencia, cerró el identificador). El servidor http fue el único proceso que escribió en ese directorio, así que podía confiar en el patrón crear-escribir-cerrar.