Как принудительно удалить файл, для которого открыт поток чтения
Я пытаюсь удалить файл для которого открыт поток чтения, но получаю ошибку:
Как удалить файл, для которого открыт поток чтения (и возможности закрыть поток — нет)?
![]()
В общем случае, удалить заблокированный файл средствами Java вряд ли удастся (как с помощью стандартных средств, так и с помощью сторонних библиотек вроде Apache Commons IO).
В Вашем случае, можете попробовать явно вызвать GC:
Однако не стоит сильно полагаться на явный вызов GC, так как он не запускает GC, а просто дает рекомендацию JVM, чтобы она запустила сборщик мусора, а вот запустит ли она его сразу после вызова – далеко не факт.
![]()
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.6.8.43486
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Java не может получить доступ к файлу, потому что он используется другим процессом
У меня есть часть кода, которая контролирует каталог для добавления файлов. Всякий раз, когда в каталог добавляется новый файл, содержимое файла выбирается и публикуется на kafka, а затем файл удаляется.
Это работает, когда я делаю один запрос, но как только я подставляю свой код 5 или 10 пользовательским запросам из jMeter, содержимое публикуется на kafka успешно, но код не может удалить файл. Я получаю сообщение FileSystemException с сообщением, что The process cannot access the file because it is being used by another process. .
Я предполагаю, что есть проблема с concurrency, которую я не вижу. Пожалуйста, помогите!
3 ответа
У меня была аналогичная проблема, а также в следующем потоке: Многопоточность в очереди при попытке загрузить динамически созданные файлы в службу очереди, и для меня потребовалось 2 дня. Благодаря Holger, который дал ответ, как описано выше, в результате чего происходит блокировка, возможно, из-за того, что создание не было выполнено полностью при чтении другим потоком, оно значительно меня спасло времени.
Мое первоначальное решение, так как было найдено много из Интернета, было:
Я изменил его на:
И все работает отлично. Чтобы обработать «как-то» несколько запусков событий ENTRY_MODIFY (дублированные файлы загружены), я выполняю удаление в файле внутри метода uploadToQueue() после его загрузки.
Надеюсь, мой подход, основанный на вышеуказанном вкладе, также поможет другим с подобной проблемой.
Глядя на ваш код, кажется, когда один файл выбран потоком для публикации снова, другой поток собирает его для публикации. Вот почему никто не может его удалить. Это должно быть только concurrency. Вы должны перепроектировать код на основе критерия: шаги, которые могут выполняться одновременно, и те, которые не могут быть. Таким образом, шаги во всем процессе:
- возьмите файл (основной поток должен это сделать)
- опубликовать файл (вызвать другой поток, чтобы сделать это)
- удалить файл (так называемый поток должен удалить его)
- проверьте, присутствует ли какой-либо файл (опять же основной поток может это сделать)
Также, когда выбран файл, вы можете прочитать его в буфер, удалить его и продолжить с публикацией. Это позволит убедиться, что основной поток не присваивает этот файл другому потоку.
Перед удалением необходимо закрыть все соединения, которые обращаются к этому файлу.
Почему процесс не может получить доступ к файлу и что делать?
Чтобы удалить или изменить файл, он обязательно должен быть свободен от других процессов. Если его уже использует какая-то программа, система накладывает запрет на редактирование элемента, так как это повредит работу программного обеспечения. В этом случае появляется сообщение «Процесс не может получить доступ к файлу, так как этот файл занят другим процессом». Чтобы это исправить, нужно освободить его. Только вот сделать подобное куда сложнее, чем кажется на первый взгляд.
Почему “Процесс не может получить доступ к файлу”?
Одновременно работать с конкретным файлом может только одна программа. Речь идет не о библиотеках общего использования, которые используются только для извлечения данных, а об элементах, предназначенных для перезаписи. Если это кэш-файл игры, здесь содержится пользовательская информация или происходит постоянная обработка данных, и Windows накладывает ограничение. Данные файлы становятся недоступными для удаления или ручного изменения до тех пор, пока мы не завершим процесс, использующий их.
Как удалить файл, если процесс не может получить доступ к файлу?
Следуя по логической цепочке, для удаления любого файла, нужно сначала выгрузить его с оперативной памяти и со всех программ. Как только он перестанет использоваться системой в каких-то процессах, элемент сразу станет доступным для удаления.
Главная сложность данного вопроса в том, чтобы найти процесс, использующий конкретный файл. Это не всегда очевидно. Часто бывает, что изображение использует какая-то игра, браузер, торрент, медиапроигрыватель. Если в первую очередь подумать на программу просмотра картинок, вы ошибетесь. Нужно смотреть куда глубже.
Как можно решить проблему «процесс не может получить доступ к файлу»:
- Unlocker – специальная программа, созданная как раз для подобных ситуаций. Она автоматически обнаруживает связанные с файлом процессы и завершает их. По сути она делает то же самое, что нужно выполнять вручную, но только в автоматическом режиме. Она имеет минимальный размер и проверена во многих системах, поэтому точно не заражена вирусами. После скачивания и установки, нужно нажать правой кнопкой мыши по файлу и выбрать «Unlock».
- Завершить связанные процессы. Обычно вполне реально догадаться, какая именно задача использует файл. Для этого нужно открыть Ctrl + Shift + Esc и развернуть список «Подробнее». Здесь будет довольно много процессов, но большинство из них системные, нужно найти те, которые были запущены пользователем. Чтобы удалить файл кэша Google Chrome, нужно закрыть все задачи Google. Для их завершения нужно нажать правой кнопкой мыши и выбрать «Снять задачу».

- Установить правильные атрибуты. К каждому файлу можно установить подходящие привилегии. Нужно нажать правой кнопкой мыши по файлу и на вкладке «Общие» установить пункт «Только чтение». После перезагрузки компьютера возможность удаления может появиться.
- Удаление в безопасном режиме. Очень часто это срабатывает, так как при данном способе запуска система не загружает все посторонние программы. Нужно кликнуть на перезапуск ПК и в момент пуска нажать клавишу F8 (может быть другая) для выбора варианта запуска. В безопасном режиме удалить можно практически любой файл.
- Снять защиту диска на запись. Она может быть установлена на программном и физическом уровне. Первым делом нужно посмотреть на накопителе (обычно это флешка), нет ли здесь специального тумблера. Рядом должна быть соответствующая пометка. В системе в редакторе реестра также следует найти параметр WriteProtect и установить ему значение 0.

Как исправить проблему при использовании консоли и IIS?
Точно такая же самая ошибка «процесс не может получить доступ к файлу» может появиться при запуске команды netsh или при выполнении настройки сайта IIS. В таком случае проблема может быть вызвана недостатком прав для выполнения действия, попытке подключения к занятым портам 80 и 443 или некорректной настройкой реестра.
3 способа исправить ошибку:
- Запустить консоль с повышенными привилегиями. Для этого в меню Пуск нужно ввести «Командная строка» и выбрать «Запуск от имени администратора».
- Переключиться на другой пулIP-адресов. Также это может сработать при конфликте между DNS и Quickbooks. Достаточно выполнить команду netsh int ipv4 set dynamicport tcp start=10000 num=1000 – затем такую же самую, но вместо tcp следует ввести udp.
- Устранить конфликты портов. Следует запустить консоль с правами админа, вставить netstat -ano и посмотреть, заняты ли порты 80 и 443. Если они не задействованы, придется перейти по пути HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\ListenOnlyList в редакторе реестра. Теперь в консоли следует ввести net stop http и в параметре реестра ListenOnlyList нужно оставить только 0.0.0.0. Остается только запустить службу повторно net start http. Если порты заняты, нужно их либо освободить, либо переопределить.

Перечисленных выше действий достаточно, чтобы исправить проблему «Процесс не может получить доступ к файлу». После выполнения процедур удастся либо удалить файл, либо восстановить нормальную работу Windows IIS 6.0 и 7.0.
Проблема Android Studio с компиляцией «Процесс не может получить доступ к файлу, поскольку он используется другим процессом».
Я знаю, что этот вопрос уже задавали раньше, но удовлетворительного ответа не было, а последний пост был три года назад. Я использую Android Studio 3.6.2 в Windows 10. Каждый раз, когда я пытаюсь скомпилировать свою программу, я получаю сообщение об ошибке «Процесс не может получить доступ к файлу, поскольку он используется другим процессом».
Теперь я знаю, что вызывает ошибку. Ранее скомпилированный файл R.jar нельзя удалить, поскольку студия Android блокирует файл. Он находится в папке \app\build\intermediates\compile_and_runtime_not_namespaced_r_class_jar\debug
Теперь, чтобы обойти проблему, я закрыл студию Android. Затем удалите R.jar, затем перезапустите студию Android и затем компилируйте. Этот процесс занимает несколько минут, и я должен делать это каждый раз. Представьте, сколько времени уходит на написание программы, когда вам приходится делать это каждый раз.
Когда об этом спрашивали о переполнении стека, ранее предлагались недопустимые кэши / перезапуск, но это не быстрее, чем то, что я сделал выше, и работает только один раз. Также пробовал Clean Project, но это не помогло.
Я использовал много компиляторов на протяжении многих лет, таких как визуальная студия, кодовые блоки и т. д., но такого никогда не было раньше, так почему же студия Android так плоха? Кто-нибудь уже нашел решение этой проблемы?