2009-10-12 12 views
9

Ich versuche, die folgende Operation in Java und bin nicht sicher, zu implementieren, wie:Wie erstelle ich eine Datei nur in Java, wenn sie noch nicht existiert?

/* 
* 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 
    } 
} 

Gibt es eine Funktion, die bereits vorhanden ist, dass ich für atomicCreateFile() verwenden kann?

bearbeiten: Uh oh, ich bin mir nicht sicher, dass File.createNewFile() ist ausreichend für meine Bedürfnisse. Was passiert, wenn ich f.createNewFile() und dann zwischen der Zeit, die es zurückgibt und ich öffne die Datei zum Schreiben, jemand anderes hat die Datei gelöscht? Gibt es eine Möglichkeit, die Datei sowohl zu erstellen als auch zu öffnen, um sie zu schreiben + zu sperren, alles auf einen Schlag? Muss ich mir darüber Gedanken machen?

Antwort

18

File.createNewFile() erstellt nur eine Datei, wenn diese noch nicht existiert.

BEARBEITEN: Basierend auf Ihrer neuen Beschreibung, die Datei nach der Erstellung sperren zu wollen, können Sie das Objekt mit dem Objekt sperren. Es gibt keine Ein-Zeilen-Erstellung und Sperre, obwohl du hoffst. Siehe auch SO question.

+0

doh! Wie habe ich das vermisst? :/ Vielen Dank. Mein Verstand war in C++ Land. –

+0

aktualisiert meine Antwort basierend auf Ihrer Bearbeitung –

+0

ok, danke. Nun, es hört sich so an, als müsste ich über außergewöhnliche Bedingungen nachdenken. (z.B.wenn die createNewFile() erfolgreich ist, aber einen Dateikanal öffnet und eine Dateisperre fehlschlägt) –

7

File.createNewFile()

Atomar schafft eine neue, leere Datei mit diesem abstrakten Pfadnamen genannt , wenn und nur wenn eine Datei mit diesem Namen noch nicht existiert. Die Überprüfung auf das Vorhandensein der Datei und die Erstellung der Datei, wenn sie nicht existiert, sind eine einzige Operation, die in Bezug auf alle anderen Dateisystemaktivitäten, die sich auf die Datei auswirken können, unteilbar ist.

EDIT

Jason, wie für Ihre Sorge, wenn Sie auf den Link lesen Sie wir Ihnen geschickt haben gibt es einen Hinweis darüber.

Hinweis: diese Methode nicht für Datei-Verriegelung verwendet werden sollte, da das resultierende Protokoll nicht gemacht werden kann zuverlässig zu arbeiten. Die FileLock Einrichtung sollte stattdessen verwendet werden.

Ich glaube, Sie wirklich, dass ein Teil lesen sollte:

alt

+0

Joachim: Kein Problem, also verwendet optimistische Sperre zum Bearbeiten – OscarRyz

+0

Danke, ich habe die Notiz gelesen, das hat das Uh ausgelöst oh. –

+0

(Leider scheint es kein Repository von Java-I/O-Paradigmen zu geben, abgesehen davon, dass man die Plattform javadocs manuell erkundet, das sind alle verfügbaren Werkzeuge ... Datei und FileLock sind manchmal in völlig verschiedenen Paketen Sie verwenden FileChannel, manchmal verwenden Sie FileOutputStream ... macht meinen Kopf manchmal drehen.) –

-1

Warum können Sie nicht testen File#exists mit?

+6

, denn zwischen dem Zeitpunkt, an dem Sie mit File.exists() testen, und dem Erstellen einer Datei, falls diese nicht existiert, hat möglicherweise jemand anderes die Datei zuerst erstellt. –

+5

Da zwischen dem Zeitpunkt, an dem 'exists()' false zurückgibt und er 'FileOutputStream' konstruiert, könnte ein anderer Prozess hineinspringen und die Datei erstellen. Eine klassische Race-Kondition. –

+18

(genau so wie ich diesen Kommentar kurz vor Joachim eingefügt habe. :-) –

-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

Ich habe den Parameter zum Dateikonstruktor in eine tatsächliche Zeichenkette geändert, falls das der Grund war, warum er fehlgeschlagen ist. – cosbor11

+0

Wenn das System eine Datei erstellt, hat es eine Handle aka "Sperre" darauf. – cosbor11

+0

Wenn Sie in die Datei schreiben, sollte sie auch ein Handle für das File-Objekt erhalten, damit kein anderer Thread darauf zugreifen oder es löschen kann. Sie könnten einen JUnit-Test schreiben, um dies zu bestätigen. Wenn Probleme auftreten, können Sie Ihre Operationen in einem synconisierten() {} -Block ausführen. – cosbor11

2

Java 7 Version mit Files#createFile:

Path out; 

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