Как узнать, какой поток блокирует файл в Java? - PullRequest
6 голосов
/ 01 февраля 2010

Я пытаюсь удалить файл, с которым ранее работал другой поток в моей программе.

Я не могу удалить файл, но я не уверен, как выяснить, какой поток может использовать файл.

Так как мне узнать, какой поток блокирует файл в Java?

Ответы [ 2 ]

7 голосов
/ 01 февраля 2010

У меня нет прямого ответа (и я не думаю, что он тоже есть, это контролируется на уровне ОС (нативном), а не на уровне JVM), и я также не вижу значения ответ (вы все еще не можете программно закрыть файл, как только выясните, какой это поток), но я думаю, вы еще не знаете, что невозможность удаления обычно возникает, когда файл все еще открыт. Это может произойти, когда вы не явно вызываете Closeable#close() на InputStream, OutputStream, Reader или Writer, который построен вокруг File в вопрос.

Базовая демонстрация:

public static void main(String[] args) throws Exception {
    File file = new File("c:/test.txt"); // Precreate this test file first.
    FileOutputStream output = new FileOutputStream(file); // This opens the file!
    System.out.println(file.delete()); // false
    output.close(); // This explicitly closes the file!
    System.out.println(file.delete()); // true
}

Другими словами, убедитесь, что во всем вашем Java IO код правильно закрывает ресурсы после использования. Обычная идиома заключается в том, чтобы сделать это в операторе try-with-resources , чтобы вы могли быть уверены, что ресурсы будут освобождены в любом случае, даже в случае IOException. Э.Г.

try (OutputStream output = new FileOutputStream(file)) {
    // ...
}

Сделайте это для любого InputStream, OutputStream, Reader и Writer и т. Д. Независимо от того, что реализует AutoCloseable, которую вы открываете себя (используя ключевое слово new).

Это технически не требуется в некоторых реализациях, таких как ByteArrayOutputStream, но для ясности просто придерживайтесь идиомы close-in-finally везде, чтобы избежать ошибочных представлений и ошибок рефакторинга.

Если вы еще не используете Java 7 или новее, используйте вместо этого try-finally идиома.

OutputStream output = null;
try {
    output = new FileOutputStream(file);
    // ...
} finally {
    if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
}

Надеюсь, это поможет выявить причину вашей конкретной проблемы.

2 голосов
/ 20 декабря 2015

Об этом вопросе я тоже пытаюсь выяснить этот ответ и задать этот вопрос и найти ответ:

Каждый раз, когда поток JVM блокирует исключительно файл , также блокируется JVM какой-то объект Jave , например, я нахожу в моем случае:

  • sun.nio.fs.NativeBuffer
  • sun.nio.ch.Util $ * 1015 буферный кэш *

Так что вам нужно просто найти этот заблокированный Java-объект и проанализировать его и Вы находите, какой поток заблокировал ваш файл.

Я не уверен, что это будет работать, если файл просто открыт (без блокировки исключительно), но я уверен, что это работает, если файл заблокирован исключительно Thread (с помощью java.nio.channels.FileLock, java.nio.channels. FileChannel и т. Д.)

Подробнее см. этот вопрос

...