2014-11-10 10 views
7

Krótka wersja: Dlaczego nie należy używać File.createNewFile() do blokowania plików? Lub bardziej szczegółowo: czy są problemy, jeśli są używane do blokowania katalogu danych aplikacji?Blokowanie istnienia pliku w Javie


Szczegóły:

Chciałbym chronić moje aplikacje katalog danych przy użyciu pliku Lock: Jeśli istnieje plik lock, katalog jest zablokowany i wyjść aplikacji z komunikatem o błędzie. Jeśli nie istnieje, zostanie utworzone i aplikacja będzie kontynuowana. Po wyjściu plik zostanie usunięty.

Blokada nie zostanie utworzona tak często (tzn. Wydajność nie jest problemem) i nie mam problemu z ręcznym usunięciem pliku blokady w przypadku wystąpienia jakiegoś błędu (tj. Nieudane usunięcie pliku nie jest problemem).

Kod wygląda mniej więcej tak:

File lockFile = new File("lock"); 
boolean lockCreated = lockFile.createNewFile(); 
if (lockCreated) 
{ 
    // do stuff 
    lockFile.delete(); 
} 
else 
{ 
    System.err.println("Lockfile exists => please retry later"); 
    // alternative: Wait and retry e.g. 5 times 
} 

teraz jestem trochę zdezorientowany o Javadoc of createNewFile():

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

Uwaga: ta metoda powinna być nie używana do blokowania plików, ponieważ wynikowy protokół nie może być wykonany niezawodnie. Należy użyć funkcji .

Jakie potencjalne problemy wymieniono w uwadze, biorąc pod uwagę sprawdzenie istnienia i tworzenie plików są atomowe?

This forum post z grudnia 2007 wskazuje, że istnieją "istotne różnice między platformami" według Javadoca z File.delete() (chociaż nie mogę znaleźć takiego stwierdzenia, ponieważ przynajmniej Java SE 1.4.2). Ale nawet gdyby istniały takie różnice: czy rzeczywiście mogą spowodować, że blokowanie się nie powiedzie (np. Dwa procesy uznają katalog danych za użyteczny w tym samym czasie)?


Uwaga: Mam nie chcą jedną z następujących czynności:

  • zablokować plik tak, że żaden inny proces może uzyskać dostęp i/lub modyfikować (większość informacji znalazłem wydaje omówić ten problem).
  • Upewnij się, że żaden inny proces nie może usunąć blokady.
  • Zsynchronizuj wiele wątków tej samej maszyny JVM (chociaż myślę, że moje rozwiązanie powinno również poradzić sobie z tym).
+1

zależy od tego, co rozumieją pod pojęciem "atomowy". jest atomowa w ramach własnej aplikacji i atomowa dla wszystkich aplikacji w systemie. Podejrzewam, że jest atomowa tylko dla twojej aplikacji i nie może nic zrobić, aby zabezpieczyć jakikolwiek inny równoległy proces przeskakiwania i wyrzucania pliku z dala od ciebie. –

+2

Możesz zaokrętować się za pomocą pliku i po prostu otworzyć port. –

+0

@MarcB: Spodziewałem się, że Javadoc będzie oznaczać ogólnoustrojową atomowość: "... to pojedyncza operacja, która jest atomowa względem ** all ** other filesystem activities_ ...". Ale dobra racja, nie myślałem o tym ... – siegi

Odpowiedz

1

Krótka odpowiedź: niezawodne blokowanie plików w Javie nie jest praktyczne.

Długa odpowiedź: problem z blokowaniem plików w dowolnym systemie operacyjnym zawsze sprowadza się do tego, z jakiego systemu pamięci pochodzi. Niemal wszystkie systemy plików z dostępem do sieci (NFS, SAMBA itp.) Mają bardzo niewiarygodne (lub co najmniej nieprzewidywalne) synchronizacje na plikach tworzone lub usuwane, co sprawia, że ​​ogólne podejście do Java jest niewskazane. W niektórych systemach, używając lokalnych systemów plików, możesz czasami dostać to, czego pragniesz. Ale musisz zrozumieć bazowy system plików i jego cechy charakterystyczne i postępować ostrożnie.

+2

Dzięki za odpowiedź! Rozumiem, że sieciowe systemy plików zachowują się nieprzewidywalnie. Dla mnie Javadoc brzmi jednak dość surowo. Tak więc Javadoc jest poprawny i jest zagwarantowane, że tworzenie czeku i pliku jest atomowe (przynajmniej dla lokalnych systemów plików) lub nie jest, a Javadoc jest niepoprawny i powinien zostać przeformułowany (np. _na podstawie najlepszego wysiłku_ ...). Dodanie raczej niespecyficznej notatki nie powinno unieważnić gwarancji przed ... – siegi

1

Javadoc z Files.createFile(…), część java.nio.file dostępna od wersji Java 7, powtarza obietnicę atomowości, ale nie wspomina nic o blokowaniu opartym na plikach.


Moje rozumowanie:

  • Każda nowsza metoda (od java.nio.file.Files) zależy od tych samych (lub podobnych) problemy, jak starszy (od java.io.File) i Javadoc jest po prostu brakuje tej informacji ...
  • ... lub nowsza metoda zachowuje się w sposób bardziej przewidywalny i poprawny.

względu na obsługę błędów i specyfikację w java.nio.file została generalnie ulepszone w porównaniu do klasy File (istniejącego odkąd JDK 1.2), zakładam, że druga alternatywa jest poprawna.


Mój wniosek: używanie tego urządzenia przy użyciu Files.createFile(…) jest w porządku.