Mam proces Java, który otwiera plik za pomocą FileReader. Jak mogę zapobiec otwarciu tego pliku przez inny proces (Java) lub przynajmniej powiadomić ten drugi proces, że plik jest już otwarty? Czy to automatycznie powoduje, że drugi proces otrzymuje wyjątek, jeśli plik jest otwarty (co rozwiązuje mój problem), czy też muszę jawnie otworzyć go w pierwszym procesie z jakąś flagą lub argumentem?
W celu wyjaśnienia:
Mam aplikację Java, która wyświetla folder i otwiera każdy plik na liście w celu jego przetworzenia. Przetwarza każdy plik po drugim. Przetwarzanie każdego pliku polega na przeczytaniu go i wykonaniu pewnych obliczeń na podstawie zawartości i trwa około 2 minut. Mam też inną aplikację Java, która robi to samo, ale zamiast tego zapisuje w pliku. Chcę mieć możliwość uruchamiania tych aplikacji w tym samym czasie, więc scenariusz wygląda tak. ReadApp wyświetla listę folderów i znajduje pliki A, B, C. Otwiera plik A i rozpoczyna odczytywanie. WriteApp wyświetla listę folderów i znajduje pliki A, B, C. Otwiera plik A, widzi, że jest otwarty (przez wyjątek lub w jakikolwiek inny sposób) i przechodzi do pliku B. ReadApp kończy plik A i kontynuuje do B. jest otwarta i kontynuuje C. Ważne jest, aby WriteApp nie t pisz, gdy ReadApp czyta ten sam plik lub odwrotnie. To są różne procesy.
Odpowiedzi:
FileChannel.lock jest prawdopodobnie tym, czego chcesz.
(Zastrzeżenie: kod nie został skompilowany i na pewno nie został przetestowany).
Zwróć uwagę na sekcję zatytułowaną „Zależności platform” w dokumencie API dla FileLock .
źródło
FileOutputStream
.).FileOutputStream
nie będzie zbyt przydatny dlaReader
.NonWritableChannelException
, ponieważlock()
próbuje uzyskać wyłączną blokadę, ale to wymaga dostępu do zapisu. Jeśli masz strumień wejściowy , możesz użyć,lock(0L, Long.MAX_VALUE, false)
który uzyskuje wspólną blokadę i wymaga tylko dostępu do odczytu. Możesz także użyćRandomAccessFile
otwartego w trybie do odczytu i zapisu, jeśli chcesz mieć wyłączną blokadę podczas czytania ... ale to zabroniłoby jednoczesnych czytelników.lock(0L, Long.MAX_VALUE, true)
, nielock(0L, Long.MAX_VALUE, false)
. ostatni argument jestboolean shared
docs.oracle.com/javase/8/docs/api/java/nio/channels/…Nie używaj klas w
java.io
pakiecie, zamiast tego użyjjava.nio
pakietu. Ten ostatni maFileLock
klasę. Możesz zastosować blokadę do plikuFileChannel
.źródło
Jeśli możesz używać Java NIO ( JDK 1.4 lub nowszej ), to myślę, że szukasz
java.nio.channels.FileChannel.lock()
FileChannel.lock ()
źródło
File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine
użyj java.nio.channels.FileLock w połączeniu z java.nio.channels.FileChannel
źródło
Może to nie jest to, czego szukasz, ale w interesie podejścia do problemu z innej perspektywy ....
Czy te dwa procesy Java mogą chcieć uzyskać dostęp do tego samego pliku w tej samej aplikacji? Może uda się po prostu przefiltrować cały dostęp do pliku jedną, zsynchronizowaną metodą (lub jeszcze lepiej, używając JSR-166 )? W ten sposób możesz kontrolować dostęp do pliku, a być może nawet ustawiać żądania dostępu do kolejki.
źródło
Użyj RandomAccessFile, pobierz jego kanał, a następnie wywołaj lock (). Kanał dostarczany przez strumienie wejściowe lub wyjściowe nie ma wystarczających uprawnień, aby prawidłowo blokować. Pamiętaj, aby wywołać funkcję unlock () w ostatnim bloku (zamknięcie pliku niekoniecznie zwalnia blokadę).
źródło
Poniżej znajduje się przykładowy fragment kodu służący do blokowania pliku do czasu zakończenia jego przetwarzania przez JVM.
źródło