使用ZipInputStream解压缩永不结束
我使用AsyncTask解压缩文件,并且一切似乎都进行得很顺利(ZIP压缩文件中的所有文件都被解压缩),但是我的解压缩方法从未完成。使用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()
的来源,似乎没有任何循环或任何可疑的东西?
我也曾尝试提取使用ZipFile
代替ZipInputStream
ZIP档案,但后来我得到以下错误:
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 Utility)。
这使我疯了,有什么可能是错的?
更新(解决)
可谓是一个非常愚蠢的问题,没有真正涉及到解压。
我从服务器下载的ZIP文件解压缩在他们面前,显然我忘了在开始解压缩操作之前,请从下载操作输出流close()
。
也许这个线程可以帮助别人谁犯了同样的愚蠢的错误。
那么,即使您关闭所有以前的输出和输入流,您的ZIP解压缩代码有时也会卡住。而且,这是a known bug:ZipInputStream#read
可以返回0
增加:
如果您的ZIP文件包含非ACSII文件名某些文件,您可以用提取面临的问题。 Android的ZipInputStream
不适用于UTF-8,CP437等。
在这种情况下Apache的百科全书应该是一个解决方案:
private boolean unpack(File zipFile, File targetDir) {
ZipFile zip = null;
try {
zip = new ZipFile(zipFile.getAbsoluteFile());
final Enumeration<ZipArchiveEntry> entries = zip.getEntries();
while(entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
if (entry.isDirectory()) {
mkdirsOrThrow(new File(targetDir, entry.getName()));
continue;
}
final File entryDestination = new File(targetDir, entry.getName());
mkdirsOrThrow(entryDestination.getParentFile());
final InputStream in = zip.getInputStream(entry);
final OutputStream out = new FileOutputStream(entryDestination);
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (zip!= null) try {
zip.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
'字符串名称= entry.getName(); zis.closeEntry(); Log.wtf(.... name);'也许?不知道。 –
问题是执行永远不会到达最后一个文件的'Log.wtf(...)',它总是不会超过'closeEntry()'...因此只输出前11个文件的名字。 – BadCash
你使用的是Android [ZipInputStream](https://developer.android.com/reference/java/util/zip/ZipInputStream.html)吗?Apache Commons中的[ZipArchiveInputStream](https://commons.apache.org/proper/commons-compress/apidocs/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.html)可能适用于您的情况。 –