Я использую AsyncTask для распаковки файла, и все, кажется, идет хорошо (все файлы в архиве ZIP извлекаются), но мой метод распаковки никогда не заканчивается.Unzipping with ZipInputStream никогда не заканчивается
Вот источник для моего распакованный класса:
public class MyUnzipper {
public static boolean unzipFileIntoDirectory(String inputFilename, String outputPath) throws Exception {
ZipInputStream zis = null;
BufferedOutputStream dest = null;
try {
File archive = new File(inputFilename);
File destinationDir = new File(outputPath);
final int BUFFER_SIZE = 1024;
zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(archive), BUFFER_SIZE));
ZipEntry entry = null;
File destFile;
while((entry = zis.getNextEntry()) != null){
destFile = new File(destinationDir, entry.getName());
if(entry.isDirectory()){
destFile.mkdirs();
}
else {
// check for and create parent directories if they don't exist
File parentDir = destFile.getParentFile();
if (null != parentDir) {
if (!parentDir.isDirectory()) {
parentDir.mkdirs();
}
}
int count;
byte data[] = new byte[BUFFER_SIZE];
dest = new BufferedOutputStream(new FileOutputStream(destFile), BUFFER_SIZE);
Log.i("MyUnzipper", "Beginning unzip of " + destFile);
while((count = zis.read(data, 0, BUFFER_SIZE)) != -1){
dest.write(data, 0, count);
Log.v("MyUnzipper", "Count = " + count);
}
dest.flush();
dest.close();
dest = null;
}
zis.closeEntry();
Log.wtf("MyUnzipper", "Unzipped entry " + entry.getName());
}
Log.wtf("MyUnzipper", "Unzip done");
}
catch(Exception e){
Log.wtf("MyUnzipper", "Unzip error");
e.printStackTrace();
return false;
}
finally {
if(null != zis)
zis.close();
if(null != dest)
dest.close();
}
return true;
}
}
Когда я отлаживать эту строку за строкой, он прекрасно работает, пока не распакованы все файлы, то он попадает в zis.closeEntry()
, и отладчик просто " уходит ", т.е. следующая строка (Log.wtf(...)
) никогда не выполняется. Моя AsyncTask никогда не заканчивается, это как если бы я застрял в бесконечном цикле ?! Но глядя на источник для ZipInputStream.closeEntry()
, похоже, там нет никаких петель или чего-то подозрительного?
Я также попытался извлекая архив ZIP с помощью ZipFile
вместо ZipInputStream
, но затем я получаю следующее сообщение об ошибке:
java.util.zip.ZipException: End Of Central Directory signature not found
Там нет ничего плохого с файлом ZIP, я проверил его с zip -v -T
на Mac OSX. Я также попробовал перемасштабировать его, используя ZIP версии 3.0 и 2.1 (оригинал был 2.0). Я могу распаковать всю версию без каких-либо проблем в Mac OSx (используя утилиту Unarchiver и Archive).
Это сводит меня с ума, что может быть неправильным?
Update (решена)
Оказывается, чтобы быть действительно глупая проблема, на самом деле не связанную с разархивирования.
Я загрузив ZIP файлы с сервера, прежде чем расстегивать их, и, видимо, я забыл позвонить close()
на выходе потока из операции загрузки перед началом работы распаковать.
Возможно, эта тема может помочь кому-то, кто совершает ту же самую глупую ошибку.
'имя String = entry.getName(); zis.closeEntry(); Log.wtf (... name); 'может быть? Без понятия. –
Проблема заключается в том, что выполнение никогда не достигает 'Log.wtf (...)' для последнего файла, оно каким-то образом не пропускает его после 'closeEntry()' ... так что просто выводит имена первых 11 файлов. – BadCash
Используете ли вы Android [ZipInputStream] (https://developer.android.com/reference/java/util/zip/ZipInputStream.html)?Вероятно, [ZipArchiveInputStream] (https://commons.apache.org/proper/commons-compress/apidocs/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.html) из Apache Commons будет работать в вашем случае. –