Все три ответа, которые уже даны, верны: вы должны закрыть базовый поток либо прямым вызовом StramSource, либо получить поток и закрыть его, либо создать поток самостоятельно и закрыть его.
Однако я уже видел, как это происходило под окнами, по крайней мере, три года: даже если вы закроете поток, на самом деле каждый поток, если вы попытаетесь переместить или удалить файл, он выдаст исключение .. если ... вы явно вызываете System.gc ().
Однако, поскольку System.gc () не является обязательным для JVM для фактического выполнения цикла сборки мусора, и, даже если это была JVM, не требуется удалять все возможные объекты мусора, у вас нет реального способа будучи уверенным, что файл можно удалить "сейчас".
У меня нет чёткого объяснения, я могу только представить, что, вероятно, реализация java.io в Windows каким-то образом кэширует дескриптор файла и не закрывает его, пока этот дескриптор не будет очищен.
Сообщалось, но я не подтвердил, что java.nio не подвержен этому поведению, потому что он имеет более низкий уровень контроля над файловыми дескрипторами.
Решение, которое я использовал в прошлом, но которое было взломано, заключалось в следующем:
- Поместить файлы для удаления в «список»
- Попросите фоновый поток периодически проверять этот список, calla System.gc и попытайтесь удалить эти файлы.
- Удалите из списка файлы, которые вам удалось удалить, и оставьте там файлы, которые еще не готовы.
Обычно «задержка» составляет порядка нескольких миллисекунд, за исключением некоторых случаев, когда файлы выживают немного дольше.
Может быть хорошей идеей также вызвать deleteOnExit для этих файлов, так что если JVM завершит работу до того, как ваш поток завершит очистку некоторых файлов, JVM попытается удалить их. Однако у deleteOnExit в то время была своя собственная ошибка, препятствующая точному удалению файла, поэтому я этого не сделал. Может быть, сегодня это решено, и вы можете доверять deleteOnExit.
Это ошибка JRE, которую я нахожу наиболее раздражающей и глупой, и не могу поверить, что она все еще существует, но, к сожалению, я обнаружил ее всего месяц назад на Windows Vista с последней установленной JRE.