Как диагностировать File.delete (), возвращение false / находит открытые потоки?

Я работаю с третьей стороной библиотека управления JPEG/EXIF (Mediautil), которая вызывает меня некоторые головные боли. Я хочу изменить данные изображения EXIF. Чтобы сделать это, я должен записать обновленную версию во временный файл, удалить оригинал и затем переименовать временный файл к настоящему имени.

Моя проблема состоит в том что File.delete() назовите сбои и возвраты false, по-видимому, потому что библиотеке все еще открыли его в некотором роде - но я сделал все, что я могу найти в API, чтобы заставить его закрыть все потоки. Еще хуже: проблема, кажется, иждивенец синхронизации и Модульные тесты, где она иногда происходит, сбой и иногда не - но код не является многопоточным.

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

Какие-либо идеи, как приняться за решение этой проблемы?

Править: Это находится на Windows XP, Java 6. И другая вещь: Я узнал это, если я звоню System.gc() перед вызовом File.delete(), это работает - по-видимому, потому что это инициировало некоторый финализатор. Таким образом, это определенно, кажется, открытый поток.

13
задан Michael Borgwardt 24 January 2010 в 21:16
поделиться

3 ответа

Я бы попросил помощи с отладчиком. Быстрое копание в java.io показывает, что единственный вероятный кандидат completion() находится в FileOutputStream. Так что вставьте туда точку останова, запустите свою программу и попробуйте заставить System.gc() запустить FileOutputStream.finalize(), чтобы освободить ваш поток. Это должно дать вам ответ, является ли это вашей проблемой или нет.

После того, как вы сможете это воспроизвести, вам необходимо начать инстанцирование инстанций FileOutputStream.end() с их окончательной доработкой. Хороший отладчик предоставит внутренние идентификаторы объектов JVM для каждого объекта, так что если вы можете отслеживать OID по мере их создания, и отслеживать их по мере завершения, то, надеюсь, вы сможете связать вызов ключа к завершению с конкретным вызовом нового нового FileOutputStream.

Однако, в зависимости от сложности вашего приложения, это может быть долгий слог.

5
ответ дан 2 December 2019 в 01:57
поделиться

Почему бы вам не переименовать файл, прежде чем получить библиотеку, чтобы открыть ее? Тогда, возможно, используйте файл Java.deleteOnexit (), чтобы удалить переименованный файл. Например:

 File jpeg = new File("image.jpg");
 File temp = new File(jpeg + ".temp.jpg");
 jpg.renameTo(temp);
 SomeObj result = exifLibrary(temp); // or exifLibrary(new FileInputStream(temp);
 OutputStream jpegStream = new FileOutputStream(jpeg);
 output.write(result.bytes();
 output.close();
 temp.deleteOnExit();
 temp.delete();
0
ответ дан 2 December 2019 в 01:57
поделиться

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

Я думаю, что вы могли бы определить реальную проблему; I.e. Что api вы используете утечки открытых ручек файлов по дизайну.

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

0
ответ дан 2 December 2019 в 01:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: