2009-03-27 14 views
9

Tengo una aplicación en la que a veces necesito leer el archivo que se está escribiendo y como resultado está bloqueado. Como he entendido desde otro questions debería capturar la IOException y volver a intentar hasta que pueda leer.cómo esperar mejor a que se libere un filelock

Pero mi pregunta es cómo sé con certeza que el archivo está bloqueado y que no es otro IOExcetpion que se produce.

Respuesta

5

Cuando abre un archivo para leer en.NET que en algún momento tratar de crear un identificador de archivo usando la función CreateFile API que establece el error code que se puede utilizar para ver qué ha fallado:

const int ERROR_SHARING_VIOLATION = 32; 
try 
{ 
    using (var stream = new FileStream("test.dat", FileMode.Open, FileAccess.Read, FileShare.Read)) 
    { 
    } 
} 
catch (IOException ex) 
{ 
    if (Marshal.GetLastWin32Error() == ERROR_SHARING_VIOLATION) 
    { 
     Console.WriteLine("The process cannot access the file because it is being used by another process."); 
    } 
} 
+2

Desafortunadamente, no puede estar seguro de que el error de Win32 fue realmente causado por la llamada a la API CreateFile. Esto podría cambiar en otra versión del marco. Para estar seguro, llame a la API de Win32 usted mismo. –

0

para leer los datos que puede hacer:

usando (FileStream fs = new FileStream (nombre del archivo, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) {.. ..}

y ahorrar en el archivo:

usando (fs = FileStream nueva archivo Stream (fileName, FileMode.Append, FileAccess.Write, FileShare.Read | FileShare.Delete)) {...}

Banderas al final de constructores describe lo que otro proceso puede hacer con el archivo. Está bien, por supuesto, si el usuario controla la escritura y lectura ...

0

se puede comparar con el tipo IOException para comprobar y ver si no es otra cosa

Tal como

if (ex is FileNotFoundException) 

Es posible que desee buscar la ayuda en System.IO. Muchas de las excepciones en esa clase heredan de IOException. Además de verificar si se trata de otro tipo de excepción, es posible que deba buscar en el mensaje de la descripción o buscar una llamada a la API de Win32 en shell32.dll. Puede haber una función allí para verificar si un archivo está bloqueado.

Además, si necesita esperar definitivamente, puede utilizar el bucle, pero si desea hacer otras acciones mientras espera, utilice un hilo asíncrono.

0

Qué quiere decir que es la lectura y la escritura en el archivo? O que una aplicación externa está escribiendo en él.

Si está leyendo y escribiendo, supongo que lo está haciendo en diferentes subprocesos, en cuyo caso eche un vistazo a la clase ReaderWriteLock, que hará esto la gestión por usted y le permitirá proporcionar tiempos de espera excedidos.

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

De lo contrario todo lo que tiene que hacer es abrir el archivo en un modo de sólo lectura. Entonces no debería tener ningún problema:

fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)); 
4

Hay una discusión útil sobre google groups la que realmente debería leer. Una de las opciones es cercana a la de Darin; sin embargo, para garantizar que obtienes el error win32 correcto, realmente deberías llamar a la API Win32 OpenFile() tú mismo (de lo contrario, realmente no sabes qué error estás recuperando).

Otro es analizar el mensaje de error: eso fallará si su aplicación se ejecuta en otra versión de idioma.

Una tercera opción es hackear dentro de la clase de excepción con reflexión para pescar el HRESULT real.

Ninguna de las alternativas es realmente tan atractiva: la jerarquía IOException se beneficiaría de unas pocas subclases en mi humilde opinión.

Cuestiones relacionadas