2010-02-01 1 views
6

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

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

Как узнать, какой поток блокирует файл в java?

+1

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

ответ

7

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

Basic демо:

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 код правильно закрытия ресурсов, после использования. The normal idiom должен сделать это в the try-with-resources statement, так что вы можете быть уверены, что ресурсы все равно будут освобождены, даже в случае IOException. Например.

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

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

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

В случае, если вы не на Java 7 или новее, используйте вместо этого ниже try-finally idiom.

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

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

+1

Отличный ответ, спасибо. – tomdee

+1

Добро пожаловать. – BalusC

2

Об этом вопросе, я также попытаться найти этот ответ, и попросить this question и найти ответ:

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

  • sun.nio.fs.NativeBuffer
  • sun.nio.ch.Util $ BufferCache

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

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

Более подробную информацию см this question