2011-10-24 27 views
10

Quiero crear un archivo SOLAMENTE si aún no existe.
un código como:Crear un archivo solo si no existe

if (!File.Exists(fileName)) 
{ 
    fileStream fs = File.Create(fileName); 
} 

Dejarlo abierto para una carrera de condición en caso de que se creará el archivo entre el "si" a la "crear".

¿Cómo puedo evitarlo?

EDIT:
cerraduras no pueden utilizarse aquí porque es un procesos diferentes (múltiples instancias de la misma aplicación).

+0

usando try {} catch {}? – ojlovecd

+0

misma aplicación? mutex? –

Respuesta

9

La respuesta de Kristian Fenn era casi lo que necesitaba, solo con un FileMode diferente. Esto es lo que estaba buscando:

FileStream fs = new FileStream(fileName, FileMode.CreateNew); 
1

Si los intentos contendientes para crear el archivo están en el mismo proceso, puede usar una instrucción lock alrededor de su código para evitar la contención.

Si no es así, ocasionalmente puede obtener una excepción cuando llama a File.Create. Simplemente manejar adecuadamente esa excepción. Probablemente sea aconsejable verificar si el archivo existe antes de crear, incluso si está manejando una excepción cuando el archivo existe porque una excepción lanzada es relativamente costosa. No sería aconsejable solo si la probabilidad de la condición de carrera es baja.

+1

Espero que no escriba el software que uso. Seguridad garantizada por encima de las conjeturas, por favor. – reinierpost

19

También puede utilizar

FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate); 

Sin embargo, usted debe buscar en el hilo de bloqueo, como si más de un hilo intenta acceder al archivo que probablemente obtendrá una excepción.

+0

MSDN no indica si ese constructor es seguro para la ejecución de los hilos, por lo que tiene razón al instar a la precaución en un entorno multiproceso. –

+1

Dos hilos que lo intenten simultáneamente obtendrán los mismos resultados que ['CreateFile'] (http://msdn.microsoft.com/en-us/library/aa363858 (VS.85) .aspx) (como' FileStream' s constructor es un contenedor sobre Win32) que se convoca al mismo tiempo: un hilo ganará. Tal como lo entiendo, a nivel de kernel esta es una operación única: un hilo no se creará mientras que el otro lo abrirá. – Richard

+0

Gracias Richard, es bueno saberlo. –

1

Primero, bloquee o monitoree. Ingrese o pruebe las API para bloquear la parte del código. En segundo lugar, puede usar FileStream API con FileMode.OpenOrCreate API. Si el archivo existe, simplemente lo usa o sino simplemente lo crea.

3

No es una solución mejor. También observe el using(var stream...) Úselo para cerrar la secuencia para evitar excepciones IO.

if (!File.Exists(filePath)) 
{ 
    using (var stream = File.Create(filePath)) { } 
} 
Cuestiones relacionadas