2009-03-26 18 views
15

Quiero abrir un archivo para leer en modo exclusivo, y si el archivo ya está abierto por algún proceso/subproceso, deseo recibir una excepción. Probé el siguiente código, pero no funcionaba, incluso si abrí foo.txt, aún puedo llegar a la declaración Console.WriteLine. ¿Algunas ideas?abrir archivo en modo exclusivo en C#

static void Main(string[] args) 
{ 
    using (Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open, 
    FileAccess.Read, FileShare.None)) 
    { 
     Console.WriteLine ("I am here"); 
    } 

    return; 
} 
+0

"incluso si abrí el foo.txt" -> ¿cómo lo abres? –

+0

Sí, Mehrdad. Lo abrí, luego ejecuté mi programa, aún podía leer la declaración Console.WriteLine. ¿Algunas ideas? – George2

+0

¿Con bloc de notas? El Bloc de notas no bloquea el archivo cuando se ejecuta. Lee el archivo en la memoria y lo vuelve a abrir para que escriba cuando lo guarde. –

Respuesta

1

se recomienda usar el miembro FileAccess.ReadWrite porque algunos archivos pueden estar ya abierta, pero que permitirá Read acceso en el archivo. Sin embargo, supongo que en condiciones no excepcionales, todos los archivos abiertos para el acceso Read/Write no permitirían su código a Write en el archivo.

Por supuesto (como ya lo explicó Mehrdad), si está utilizando un editor como el Bloc de notas para abrir el archivo como prueba, no podrá restringir el acceso porque el Bloc de notas no bloquea el archivo en absoluto.

+0

Gracias, Cerebrus, tiene razón y estoy usando un bloc de notas para abrirlo y ejecutar mi programa para probar. ¿Alguna idea para verificar si un archivo está abierto o no (por ejemplo, quiero que mi código pueda verificar si el bloc de notas lo ha abierto)? – George2

+0

No, no creo que exista ... excepto capturando la IOException en el código que intenta leer el archivo posteriormente. – Cerebrus

+0

Mi situación es que un subproceso es serialización (mediante serialización de XML) en el archivo, se lee otro subproceso del lector de este archivo. No quiero que el hilo del lector opere en este archivo mientras la serialización XML está en proceso, ¿alguna idea? – George2

16

Lo que estás haciendo es lo correcto. Probablemente solo lo estás probando incorrectamente. Debería abrirlo con un programa que bloquea el archivo cuando está abierto. El bloc de notas no funcionaría. Puede ejecutar la aplicación dos veces para ver:

static void Main(string[] args) 
{ 
    // Make sure test.txt exists before running. Run this app twice to see. 
    File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None); 
    Console.ReadKey(); 
} 
+0

Gracias Mehrdad, de todos modos para comprobar si un archivo ya está abierto por otro hilo/proceso? – George2

+0

No creo que haya una forma de averiguar si un proceso ha abierto un archivo y está trabajando en él. Técnicamente, el archivo ya no está abierto después de que el bloc de notas lo carga en la memoria. Creo que esta es la manera correcta de hacerlo ya que el bloc de notas u otros programas no pueden abrirlo de nuevo (para leer o guardar) lo que está bien, creo. –

+0

Gracias Mehrdad, he probado que tienes razón. mi situación es que un hilo es serialización (usando serialización de XML) para el archivo, otro hilo de lector se lee de este archivo. No quiero que el hilo del lector opere en este archivo mientras la serialización XML está en proceso, ¿alguna idea? – George2

2

FileShare.NONE sólo funcionará si otro proceso también ha abierto el archivo sin que llegue a ser compartida para lecturas.

Los programas como el Bloc de notas y Visual Studio no bloquean los archivos de texto.

+0

Gracias Jakob, de todos modos para comprobar si un archivo ya está abierto por otro hilo/proceso? – George2

+0

Hola, Jakob, mi situación es que un hilo es serialización (usando serialización XML) en el archivo, otro hilo lector se lee de este archivo. No quiero que el hilo del lector opere en este archivo mientras la serialización XML está en proceso, ¿alguna idea? – George2

+0

¿Cómo está serializando? Al serializar, debe abrir el archivo exclusivamente (es decir, FileAccess.Write y FileShare.None). –

3

Lo que ha hecho es correcto.

Si necesita lo están todos los archivos que ya están abiertos, entonces hay una manera de ver por NtQuerySystemInformation

Usted puede obtener idea de http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx

la que se lleva todos los archivos abiertos en un directorio que puede .. extenderse a un solo archivo si abre o no ...

+0

Gracias lakshmanaraj, mi situación es que un hilo es una serialización (usando serialización XML) para el archivo, otro hilo lector se lee de este archivo. No quiero que el hilo del lector opere en este archivo mientras la serialización XML está en proceso, ¿alguna idea? – George2

+0

Puede bloquear el archivo o hacer un mutex estableciendo un semáforo en la operación – lakshmanaraj

+0

, el nombre del archivo es arbitrario, por lo que es difícil de bloquear. Más detalles, copio archivos arbitrarios desde la máquina remota a la máquina local usando el hilo del escritor, y un hilo del lector escaneará la carpeta y leerá la información de los nuevos archivos venideros – George2

2

prueba que escribiendo un programa en modo consola simple que abre el archivo y luego espera:

static void Main(string args[]) 
{ 
    using (FileStream f = File.Open("c:\\software\\code.txt", FileMode.Open, FileAccess.Read, FileShare.None)) 
    { 
     Console.Write("File is open. Press Enter when done."); 
     Console.ReadLine(); 
    } 
} 

Ejecute ese programa desde la línea de comandos (u otra instancia de Visual Studio) y luego ejecute su programa. De esta forma, puede jugar con diferentes valores para FileMode y FileShare para asegurarse de que su programa reaccione correctamente en todos los casos.

Y, no, no tiene que comprobar para ver si el archivo está abierto primero. Su código debería arrojar una excepción si el archivo ya está abierto. Entonces, todo lo que tiene que hacer es manejar esa excepción.

+0

Hola Jim, mi situación es que un hilo está copiando un archivo (usando el método File.Move) y se lee otro hilo del archivo. No quiero que el hilo del lector lea una parte del archivo mientras la copia está en proceso (esta es la razón por la que quiero tener el modo abierto exclusivo), ¿solucionó este problema mi problema? – George2

+0

Sí, su código resuelve ese problema. No abrirá el archivo si File.Move está en el medio de copiarlo. –

+0

Jim, ¿cómo sé si algún programa (!) Lo está abriendo? Cualquiera bloc de notas o algo más. ¿O cómo sé si se está copiando en este momento? –

Cuestiones relacionadas