У меня есть процесс Java, который открывает файл с помощью FileReader. Как я могу предотвратить открытие этого файла другим (Java) процессом или, по крайней мере, уведомить этот второй процесс о том, что файл уже открыт? Это автоматически приводит к тому, что второй процесс получает исключение, если файл открыт (что решает мою проблему), или мне нужно явно открывать его в первом процессе с каким-то флагом или аргументом?
Чтобы уточнить:
У меня есть приложение Java, которое перечисляет папку и открывает каждый файл в списке для его обработки. Он обрабатывает каждый файл за другим. Обработка каждого файла состоит из его чтения и выполнения некоторых вычислений на основе содержимого и занимает около 2 минут. У меня также есть другое приложение Java, которое делает то же самое, но вместо этого записывает в файл. Я хочу иметь возможность запускать эти приложения одновременно, чтобы сценарий выглядел следующим образом. ReadApp перечисляет папку и находит файлы A, B, C. Он открывает файл A и начинает чтение. WriteApp выводит список папок и находит файлы A, B, C. Он открывает файл A, видит, что он открыт (по исключению или другим способом), и переходит к файлу B. ReadApp завершает файл A и переходит к B. Он видит, что он открыт и продолжает C. Очень важно, чтобы WriteApp не t писать, пока ReadApp читает тот же файл, или наоборот. Это разные процессы.
Ответы:
FileChannel.lock, вероятно, то, что вам нужно.
(Отказ от ответственности: код не компилируется и, конечно же, не тестируется.)
Обратите внимание на раздел, озаглавленный «Зависимости платформ» в документации API для FileLock .
источник
FileOutputStream
).FileOutputStream
не будет много пользы дляReader
.NonWritableChannelException
, потому чтоlock()
пытается получить эксклюзивную блокировку, но для этого требуется доступ на запись. Если у вас есть входной поток, вы можете использовать его,lock(0L, Long.MAX_VALUE, false)
который получает общую блокировку и требует только доступа для чтения. Вы также можете использоватьRandomAccessFile
открытый в режиме чтения-записи, если вы хотите исключительную блокировку при чтении ... но это запретит одновременное чтение.lock(0L, Long.MAX_VALUE, true)
, что нетlock(0L, Long.MAX_VALUE, false)
. последний аргумент тамboolean shared
docs.oracle.com/javase/8/docs/api/java/nio/channels/…Не используйте классы в
java.io
пакете, вместо этого используйтеjava.nio
пакет. Последний имеетFileLock
класс. Вы можете применить блокировку к файлуFileChannel
.источник
Если вы можете использовать Java NIO ( JDK 1.4 или выше ), я думаю, вы ищете
java.nio.channels.FileChannel.lock()
FileChannel.lock ()
источник
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
используйте java.nio.channels.FileLock в сочетании с java.nio.channels.FileChannel
источник
Возможно, это не то, что вы ищете, но чтобы взглянуть на проблему под другим углом ...
Могут ли эти два процесса Java получить доступ к одному и тому же файлу в одном приложении? Возможно, вы можете просто отфильтровать весь доступ к файлу с помощью единственного синхронизированного метода (или, что еще лучше, с помощью JSR-166 )? Таким образом, вы можете контролировать доступ к файлу и, возможно, даже ставить запросы доступа в очередь.
источник
Используйте RandomAccessFile, получите его канал, затем вызовите lock (). Канал, предоставляемый потоками ввода или вывода, не имеет достаточных прав для правильной блокировки. Обязательно вызовите unlock () в блоке finally (закрытие файла не обязательно снимает блокировку).
источник
Ниже приведен пример кода фрагмента для блокировки файла до тех пор, пока он не будет обработан JVM.
источник
Используйте это для unix, если вы переносите с помощью winscp или ftp:
источник