2010-11-29 5 views
5

¿Puedo usar el constructor FileStream para asegurar que solo un proceso tenga acceso a un archivo a la vez? ¿Funcionará el siguiente código?¿Puedo usar FileStream para implementar un bloqueo de archivos?

public static IDisposable AcquireFileLock() { 
    IDisposable lockObj; 
    do { 
     // spinlock - continually try to open the file until we succeed 
     lockObj = TryOpenLockFile(); 

     // sleep for a little bit to let someone else have a go if we fail 
     if (lockObj == null) Thread.Sleep(100); 
    } 
    while (lockObj == null); 

    return lockObj; 
} 

private static FileStream TryOpenLockFile() { 
    try { 
     return new FileStream(s_LockFileName, FileMode.Create, FileAccess.Read, FileShare.None); 
    } 
    catch (IOException) { 
     return null; 
    } 
} 

En particular, es el comportamiento con FileMode.Create WRT atómica otros procesos? ¿Hay algo más que deba usar?

EDITAR: para ser más específicos, esto es en Microsoft CLR utilizando archivos locales en una sola máquina.

+0

¡Esto se ve bien! ¿Quién limpia el archivo de bloqueo? Probablemente no exista ninguna necesidad funcional de hacerlo ya que la invocación del controlador 'FileStream' siempre sobrescribe el archivo de bloqueo existente. –

+0

Para la limpieza, siempre puedo 'intentar {File.Delete (...)}' e ignorar cualquier excepción (ya que eso significa que otro proceso ha tomado el bloqueo mientras tanto) ... – thecoop

Respuesta

2

Esto hará lo que quiera. FileShare.None es la parte importante.

Si todas las aplicaciones de escritor están en la misma computadora, también puede usar named Mutex para lograr el mismo objetivo sin necesidad de un archivo físico o mediar en el acceso a archivos si no le importa quién escribe en el archivo (solo que las escrituras no son concurrentes). Esto podría evitar tener que volver a abrir el archivo cada vez y proporcionar una semántica de bloqueo en lugar de su ciclo Sleep (mejor rendimiento).

Tenga en cuenta que cualquier proceso puede ocupar su archivo (Mutex) si el nombre no se trata como un secreto, es decir, la información que debe mantenerse segura.

+2

Un Mutex solo funciona en el mismo computadora. Los bloqueos de archivos funcionan en una red. – Gabe

+0

@Gabe - no está claro cuál es el caso de uso, pero tiene razón –

1

Esto funcionará, teniendo en cuenta las siguientes salvedades:

  • Usted está en Windows (en Linux a través de Mono, esto no se sostiene desde bloqueos de archivo son de carácter consultivo, por lo que su método siempre tiene éxito)
  • usted está accediendo a un archivo local (SMB también es probable que funcione, pero NFS o WebDAV es casi seguro que no lo hará)
  • la captura de IOException es probablemente demasiado amplio, es necesario verificar específicamente que fracasó a causa de una violación de distribución
+0

IOException es la que se lanza cuando el archivo ya está bloqueado, no puedo ver nada más específico:/ – thecoop

+0

Puede consultar HResult para ver si tiene un código de error de Win32, o si falla, puede (ugh) verificar el texto del mensaje –

Cuestiones relacionadas