Файл Java.delete() зависает или занимает слишком много времени

#java

Вопрос:

Я просто удаляю файл на основе фильтра

 public void delete(String folder, String filter){
   File f = new File(path);
   String[] files = f.list();
   for (string s : files){
      if (s.indexOf(filter) >= 0){
          new File(folder   s).delete(); 
      }
   }
}
 

Обычно это проходит хорошо за несколько микросекунд.

Однако иногда пользователи сообщают, что этот раздел зависает. Если приложение перестает отвечать на запросы слишком долго, я убиваю его и хватаю трассировку стека, и именно здесь находится поток:

в java.io.WinNTFileSystem.удалить

Иногда это также происходит при записи в файл. Мне интересно, может ли файл быть заблокирован JVM. Есть ли способ проверить это?

Комментарии:

1. Это, скорее всего, проблема Windows. Файл может быть заблокирован или аналогичен.

2. Вы пытаетесь удалить файлы с помощью удаленной файловой системы? Если это так, то может произойти все, что угодно, в том числе ничего.

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

4. Не используйте delete() . Попробуйте использовать Files.delete() .

5. Проблема в том, что я вижу это не только в File.delete (), но и при записи в файлы. Вместо этого я мог бы попытаться преобразовать все манипуляции с файлами в файлы, это хорошая идея.

Ответ №1:

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

Java NIO имеет некоторые функции, которые могут помочь, файловый канал, блокировка файлов. Это не здорово.

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

 File file = new File(fileName);
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

FileLock lock = channel.lock();
if(lock.isValid() amp;amp; !lock.isShared()){
  // lock is exclusive, you should be able to delete if you have permissions
} else {
  // cannot get lock
}
channel.close();
 

Комментарии:

1. Было бы ожидаемым поведением для зависания системного вызова с java, если бы файл действительно был заблокирован? Звучит как невероятно плохой дизайн, если это так.

2. @Джейк, я в этом не уверен. Похоже, это должно быть воспроизводимо локально, если открыть файл в чем-то вроде блокнота и попытаться удалить его с помощью простой тестовой программы.

3. Я сделал это, но безуспешно. Открыл его в блокноте, внес некоторые изменения без сохранения. Также попытался открыть его в eclipse, но, к сожалению, не смог воспроизвести. Спасибо за помощь!

4. если вы работаете в Windows, возможно, вы могли бы попробовать перейти в файл .zip или .jar. Windows 10 позволит вам просмотреть его, но на самом деле он не извлечен. Обычно я не могу удалить (из проводника Windows) архив, который просматриваю, вариант использования для меня похож на мою целевую папку maven, когда я просматриваю содержимое архива.