2009-10-12 24 views
9

Estoy tratando de poner en práctica la operación siguiente en Java y no estoy seguro de cómo:cómo crear un archivo en Java solo si aún no existe?

/* 
* write data (Data is defined in my package) 
* to a file only if it does not exist, return success 
*/ 
boolean writeData(File f, Data d) 
{ 
    FileOutputStream fos = null; 
    try 
    { 
     fos = atomicCreateFile(f); 
     if (fos != null) 
     { 
      /* write data here */ 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
    finally 
    { 
     fos.close(); // needs to be wrapped in an exception block 
    } 
} 

¿Existe una función que existe ya que puedo usar para atomicCreateFile()?

editar: Uh oh, no estoy seguro de que File.createNewFile() sea suficiente para mis necesidades. ¿Qué pasa si llamo al f.createNewFile() y luego entre el momento en que regresa y abro el archivo para escribir, alguien más ha eliminado el archivo? ¿Hay alguna manera de que pueda crear el archivo y abrirlo para escribir + bloquearlo, todo de una sola vez? ¿Debo preocuparme por esto?

Respuesta

18

File.createNewFile() solo crea un archivo si no existe uno.

EDITAR: En función de su nueva descripción de querer bloquear el archivo después de haberlo creado, puede usar el objeto java.nio.channels.FileLock para bloquear el archivo. No hay una sola línea para crear y bloquear, aunque sí lo estás esperando. Además, vea esto SO question.

+0

DOH! ¿Cómo extrañé eso? :/ Gracias. Mi mente ha estado en tierra C++. –

+0

actualizó mi respuesta en función de su edición –

+0

bien, gracias. Bueno, parece que tengo que pensar detenidamente sobre las condiciones excepcionales. (p.ej.si el createNewFile() tiene éxito pero abrir un canal de archivos y obtener un bloqueo de archivos falla) –

7

File.createNewFile()

Atómicamente crea un nuevo archivo, vacía denominada por esta vía de acceso abstracta si y sólo si un archivo con este nombre todavía no existe. La verificación de la existencia del archivo y la creación del archivo, si no existe, es una operación única que es atómica con respecto a todas las demás actividades del sistema de archivos que pueden afectar el archivo.

EDITAR

Jason, como por su preocupación, si sigues leyendo el enlace que le enviamos hay una nota sobre eso.

Nota: este método no debe usarse para bloqueo de archivos, como el protocolo resultante no puede ser hecho para trabajar de forma fiable. En su lugar, se debe usar la instalación FileLock.

creo que realmente debería leer esa parte también:

alt

+0

Joachim: No hay problema, entonces usa un bloqueo optimista para editar – OscarRyz

+0

Gracias, leí la nota, eso es lo que activó el Uh oh. –

+0

(Lamentablemente, no parece haber un repositorio de paradigmas de E/S de Java, además de explorar manualmente la plataforma javadocs, que dice que estas son todas las herramientas que tiene disponibles ... File y FileLock están en paquetes completamente diferentes, a veces usas FileChannel, algunas veces usas FileOutputStream ... a veces me da vueltas la cabeza.) –

-1

¿Por qué no se puede probar usando File#exists?

+6

porque entre el momento en que prueba con File.exists() y va a crear un archivo si no existe, es posible que alguien más haya creado el archivo primero. –

+5

Porque entre el tiempo 'exists()' devuelve false y él construye 'FileOutputStream', otro proceso podría saltar y crear el archivo. Una condición de carrera clásica. –

+18

(de la misma manera en que me resbalé en ese comentario justo antes de Joachim. :-) –

-2
//myFile should only be created using this method to ensure thread safety 
public synchronized File getMyFile(){ 
    File file = new File("path/to/myfile.ext"); 
    if(!file.exists()){ 
    file.getParentFile().mkdirs(); 
    file.createNewFile(); 
    } 
    return file; 
} 
+0

Cambié el parámetro al constructor de Archivos a una cadena real en caso de que sea por eso que estaba fallando. – cosbor11

+0

Cuando el sistema está creando un archivo, tendrá un asa alias "bloqueo" en él. – cosbor11

+0

Cuando escribe en el archivo, también debe obtener un control sobre el objeto File para que ningún otro hilo pueda acceder a él o eliminarlo. Podría escribir una prueba JUnit para confirmarlo. Si se encuentra con algún problema, puede ejecutar sus operaciones en un bloque synconized() {}. – cosbor11

2

la versión de Java 7 con Files#createFile:

Path out; 

try { 
    out = Files.createFile(Paths.get("my-file.txt")); 
} catch (FileAlreadyExistsException faee) { 
    out = Paths.get("my-file.txt"); 
} 
Cuestiones relacionadas