Извлечение файлов из zip архива

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
Ответить
Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Извлечение файлов из zip архива

Сообщение KamiSempai » 17 фев 2015, 19:25

Есть у меня на вооружении метод по извлечению архива в папку.

[syntax=java5] public static boolean decompress(File zipFile, File targetDirectory) {
boolean result = true;
ZipInputStream zis = null;
try {
zis = new ZipInputStream(
new BufferedInputStream(new FileInputStream(zipFile)));
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
try {
ZipEntry ze;
int count;
byte[] buffer = new byte[8192];
while ((ze = zis.getNextEntry()) != null) {
Log.d("Zip", "Decompressing: " + ze.getName());
File file = new File(targetDirectory, ze.getName());
File dir = ze.isDirectory() ? file : file.getParentFile();
if (!dir.isDirectory() && !dir.mkdirs())
throw new FileNotFoundException("Failed to ensure directory: " +
dir.getAbsolutePath());
if (ze.isDirectory())
continue;
FileOutputStream fout = new FileOutputStream(file);
try {
long totalBytes = 0;
while ((count = zis.read(buffer)) != -1) {
totalBytes += count;
fout.write(buffer, 0, count);
}
zis.closeEntry();
Log.d("Zip", "Total bytes: " + totalBytes);
Log.d("Zip", "Completed: " + ze.getName());
if (!file.exists())
Log.d("Zip", "Ops!!! File not exists!!!");
} catch (Exception e) {
e.printStackTrace();
result = false;
} finally {
fout.close();
}
}
} catch (Exception e) {
e.printStackTrace();
result = false;
} finally {
try {
zis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}[/syntax]
Дело в том, что он извлекает не все файлы. Если смотреть по логам, иногда я вижу следующее:
Decompressing: backup_info.xml
Total bytes: 247
Completed: backup_info.xml
Decompressing: common.db
Total bytes: 212992
Completed: common.db
Ops!!! File not exists!!!
Decompressing: user_def_user.db
Total bytes: 102400
Completed: user_def_user.db
Получается, файл "common.db" находится в архиве, его распаковка прошла успешно, было с читано 212992 байт. Но сам файл при этом не существует! Как такое вообще может быть? Ошибка происходит не всегда. Иногда все распаковывается. Ошибка в основном при распаковке "common.db".

Не пойму в чем дело. Неужто процедура с ошибкой?
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Извлечение файлов из zip архива

Сообщение klblk » 18 фев 2015, 08:47

Явных проблем не вижу. Потому буду советовать глупости:
1. Если проверку сделать уже после fout.close()?
2. Если сделать буфер поменьше? побольше?

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Извлечение файлов из zip архива

Сообщение KamiSempai » 18 фев 2015, 11:21

Первое предположение сразу не подходит. Если открыть папку с распакованными файлами, того файла действительно нет.
Второй вариант нужно попробовать. Позже отпишусь.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Извлечение файлов из zip архива

Сообщение klblk » 18 фев 2015, 11:35

По поводу первого варианта, просто подумалось может открытый FileOutputStream и file.exists() как-то конфликтуют.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Извлечение файлов из zip архива

Сообщение KamiSempai » 18 фев 2015, 15:27

Методом не хитрых манипуляций удалось выяснить, что частота возникновения ошибки увеличивается с уменьшением буфера (при буфере = 2, пропадает уже первый файл), а при его увеличении вероятность возникновения ошибки уменьшается. Если указать размер буфера 10000, ошибка случается значительно реже.

Что меня больше всего удивляет, так это то, что подобными примерами заполонен весь интернет и ни один из них не обошла эта ошибка.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Ответить