Проверьте, открыт ли файл
Мне нужно написать пользовательский пакетный файл переименования. Я сделал большую часть этого, но я не могу понять, как проверить, открыт ли файл. Я просто использую java.io.File
пакет и есть canWrite()
метод, но это, кажется, не проверяет, используется ли файл другой программой. Любые идеи о том, как я могу сделать эту работу?
8 ответов
Использование библиотеки Apache Commons IO...
boolean isFileUnlocked = false;
try {
org.apache.commons.io.FileUtils.touch(yourFile);
isFileUnlocked = true;
} catch (IOException e) {
isFileUnlocked = false;
}
if(isFileUnlocked){
// Do stuff you need to do with a file that is NOT locked.
} else {
// Do stuff you need to do with a file that IS locked
}
(Вопросы и ответы о том, как работать с блокировками "открытого файла" Windows... не о том, как реализовать такую блокировку переносимо.)
Весь этот вопрос чреват проблемами переносимости и условиями гонки:
- Вы можете попробовать использовать FileLock, но он не обязательно поддерживается для вашей ОС и / или файловой системы.
- Похоже, что в Windows вы не сможете использовать FileLock, если другое приложение открыло файл определенным образом.
- Даже если вам удалось использовать
FileLock
или что-то еще, у вас все еще есть проблема, что что-то может войти и открыть файл между тем, как вы проверяете файл и выполняете его переименование.
Более простое, хотя и непереносимое решение - просто попробовать переименовать (или что-то еще, что вы пытаетесь сделать) и диагностировать возвращаемое значение и / или любые исключения Java, возникающие из-за открытых файлов.
Заметки:
Если вы используете
Files
API вместоFile
API вы получите больше информации в случае сбоя.В системах (например, Linux), где вам разрешено переименовывать заблокированный или открытый файл, вы не получите никаких результатов или исключений. Операция будет просто успешной. Однако в таких системах вам, как правило, не нужно беспокоиться, если файл уже открыт, поскольку ОС не блокирует файлы при открытии.
// TO CHECK WHETHER A FILE IS OPENED
// OR NOT (not for .txt files)
// the file we want to check
String fileName = "C:\\Text.xlsx";
File file = new File(fileName);
// try to rename the file with the same name
File sameFileName = new File(fileName);
if(file.renameTo(sameFileName)){
// if the file is renamed
System.out.println("file is closed");
}else{
// if the file didnt accept the renaming operation
System.out.println("file is opened");
}
В Windows я нашел ответ /questions/26057734/proverte-zablokirovan-li-fajl-v-java/26057765#26057765 используя
fileIsLocked = !file.renameTo(file)
наиболее полезно, поскольку позволяет избежать ложных срабатываний при обработке защищенных от записи файлов.
org.apache.commons.io.FileUtils.touch(yourFile)
не проверяет, открыт ли ваш файл или нет. Вместо этого он изменяет временную метку файла на текущее время.
Я использовал IOException, и он работает просто отлично:
try
{
String filePath = "C:\sheet.xlsx";
FileWriter fw = new FileWriter(filePath );
}
catch (IOException e)
{
System.out.println("File is open");
}
Привет, я очень надеюсь, что это поможет.
Я пробовал все варианты раньше, и ни один из них не работает на Windows Единственная мысль, которая помогла мне добиться этого, была попытка переместить файл. Событие в том же месте под ATOMIC_MOVE. Если файл записывается другой программой или потоком Java, это определенно приведет к исключению.
try{
Files.move(Paths.get(currentFile.getPath()),
Paths.get(currentFile.getPath()), StandardCopyOption.ATOMIC_MOVE);
// DO YOUR STUFF HERE SINCE IT IS NOT BEING WRITTEN BY ANOTHER PROGRAM
} catch (Exception e){
// DO NOT WRITE THEN SINCE THE FILE IS BEING WRITTEN BY ANOTHER PROGRAM
}
Я не думаю, что вы когда-либо получите окончательное решение для этого, операционная система не обязательно скажет вам, открыт файл или нет.
Вы можете получить некоторый пробег из java.nio.channels.FileLock
, хотя Javadoc загружен предостережениями.
Если файл используется FileOutputStream fileOutputStream = new FileOutputStream(file);
возвращает сообщение java.io.FileNotFoundException со словом "Процесс не может получить доступ к файлу, поскольку он используется другим процессом" в сообщении об исключении.