Подтвердить что ты не робот

Проверьте, открыт ли файл

Мне нужно написать собственный пакетный переименователь файлов. У меня есть основная часть этого, но я не могу понять, как проверить, открыт ли файл. Я просто использую пакет java.io.File, и есть метод canWrite(), но, похоже, он не проверяет, используется ли файл другой программой. Любые идеи о том, как я могу сделать эту работу?

4b9b3361

Ответ 1

Использование библиотеки ввода-вывода Apache Commons...

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
}

Ответ 2

(Q & A описывает, как работать с блокировками "открытого файла Windows"... не так, как реализовать этот вид блокировки портативно.)

Вся эта проблема чревата проблемами мобильности и условиями гонки:

  • Вы можете попробовать использовать FileLock, но это не обязательно поддерживается для вашей ОС и/или файловой системы.
  • Похоже, что в Windows вы не сможете использовать FileLock, если другое приложение открыло файл определенным образом.
  • Даже если вам удавалось использовать FileLock или что-то еще, у вас все еще есть проблема, что что-то может появиться и открыть файл между вами, проверяющим файл и выполняющим переименование.

Более простое и (возможно) более надежное решение - просто попробовать переименовать (или что бы вы ни пытались сделать) и диагностировать возвращаемое значение и/или любые исключения Java, возникающие из-за открытых файлов.

Примечания:

  • Если вы используете API Files вместо API File, вы получите больше информации в случае сбоя.

  • В системах, где вам разрешено переименовать (или что-то еще) заблокированный или открытый файл, вы не получите никакого результата или исключения. Операция будет успешной.

Ответ 3

Лучше всего установить исключительную блокировку файла. Если файл открыт другими процессами, вы получите исключение. Например,

File file = new File(fileName);
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
// Get an exclusive lock on the whole file
FileLock lock = channel.lock();
try {
    lock = channel.tryLock();
    // Ok. You get the lock
} catch (OverlappingFileLockException e) {
    // File is open by someone else
} finally {
    lock.release();
}

Ответ 4

    //  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");
    }

Ответ 5

Я не думаю, что вы когда-нибудь получите окончательное решение для этого, операционная система не обязательно скажет вам, открыт ли файл или нет.

Вы можете получить пробег из java.nio.channels.FileLock, хотя javadoc загружается с оговорками.

Ответ 6

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");
}

Ответ 7

В Windows я нашел ответ fooobar.com/questions/137912/..., используя

fileIsLocked = !file.renameTo(file)

наиболее полезно, так как он избегает ложных срабатываний при обработке защищенных от записи файлов.

Ответ 8

Если файл используется, FileOutputStream fileOutputStream = new FileOutputStream(file); возвращает java.io.FileNotFoundException с "Процесс не может получить доступ к файлу, потому что он используется другим процессом" в сообщении об исключении.