2009-10-12 26 views
9

Próbuję realizować następujące działania w Javie i nie jestem pewien, jak:jak utworzyć plik w Javie, tylko jeśli jeszcze nie istnieje?

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

Czy istnieje funkcja, która już istnieje, że można używać do atomicCreateFile()?

edytuj: Uh oh, nie jestem pewien, że File.createNewFile() jest wystarczająca dla moich potrzeb. Co się stanie, jeśli zadzwonię pod numer f.createNewFile(), a następnie pomiędzy czasem, który zwróci i otworzę plik do napisania, ktoś inny usunął plik? Czy istnieje sposób, w jaki mogę zarówno stworzyć plik i otworzyć go do pisania + zablokować go, wszystko za jednym zamachem? Czy muszę się tym martwić?

Odpowiedz

18

File.createNewFile() tworzy tylko plik, jeśli jeszcze nie istnieje.

EDYTOWANIE: Na podstawie nowego opisu, w którym chcesz zablokować plik po jego utworzeniu, możesz użyć obiektu java.nio.channels.FileLock do zablokowania pliku. Nie ma jednej linii do tworzenia i blokowania, chociaż masz nadzieję. Zobacz także SO question.

+0

doh! jak to przegapiłem? :/ dzięki. Mój umysł był w ziemi C++. –

+0

zaktualizowałem moją odpowiedź na podstawie twojej edycji –

+0

ok, dziękuję. Wygląda na to, że muszę dokładnie przemyśleć wyjątkowe warunki. (na przykład.jeśli funkcja createNewFile() powiedzie się, ale otworzy się kanał plików i zablokowanie pliku się nie powiedzie) –

7

File.createNewFile()

atomowo tworzy nowy, pusty plik o nazwie o tej abstrakcyjnej ścieżki wtedy i tylko wtedy plik o tej nazwie jeszcze nie istnieje. Sprawdzenie istnienia pliku i utworzenie pliku, jeśli nie istnieje, to pojedyncza operacja, która jest atomowa w odniesieniu do wszystkich innych czynności systemu plików, które mogą wpłynąć na plik.

EDIT

Jason, jak za troskę, jeśli zachować czytania link my wysłałeś Jest uwaga o tym.

Uwaga: metoda ta nie powinna być stosowana do plików blokowaniem, jak otrzymany protokół nie może być wykonana pracować niezawodnie. Zamiast tego należy użyć obiektu FileLock.

myślę, że naprawdę powinien przeczytać tę część za:

alt

+0

Joachim: Nie ma problemu, więc używa optymistycznej blokady do edycji – OscarRyz

+0

Dzięki, przeczytałem notatkę, to właśnie spowodowało Uh oh. –

+0

(Niestety, nie ma tam repozytorium paradygmatów Java I/O, poza ręcznym badaniem platformy javadocs, która mówi, że są to wszystkie dostępne narzędzia ... Plik i FileLock są w zupełnie innych pakietach, czasami używasz FileChannel, czasami używasz FileOutputStream ... sprawia, że ​​czasami kręci mi się w głowie.) –

-1

Dlaczego nie można przetestować za pomocą File#exists?

+6

ponieważ między czasem testowania przy użyciu File.exists(), a idziesz do utworzenia pliku, jeśli nie istnieje, ktoś inny mógł najpierw utworzyć plik. –

+5

Ponieważ między czasem 'exists()' zwraca wartość false i konstruuje 'FileOutputStream', może jakiś inny proces mógł wskoczyć i utworzyć plik. Klasyczny wyścig. –

+18

(tak samo wpadłem w ten komentarz tuż przed Joachimem. :-) –

-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

Zmieniłem parametr na konstruktor pliku na rzeczywisty ciąg w przypadku, dla którego to się nie udało. – cosbor11

+0

Gdy system tworzy plik, będzie miał na sobie uchwyt zwany "blokadą". – cosbor11

+0

Podczas zapisu do pliku powinien również uzyskać uchwyt obiektu File, aby żaden inny wątek nie mógł uzyskać do niego dostępu lub go usunąć. Możesz to zrobić, aby to potwierdzić. Jeśli napotkasz jakiekolwiek problemy, możesz uruchomić swoje operacje w zsynchronizowanym() {} bloku. – cosbor11

2

Java 7 wersja z Files#createFile:

Path out; 

try { 
    out = Files.createFile(Paths.get("my-file.txt")); 
} catch (FileAlreadyExistsException faee) { 
    out = Paths.get("my-file.txt"); 
} 
Powiązane problemy