我正在使用AsyncTask解压缩一个文件,一切似乎都很顺利(ZIP存档中的所有文件都被解压缩),但我的解压缩方法永远不会完成 .
这是我的解压缩类的来源:
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()
,调试器只是"goes away",即下一行( Log.wtf(...)
)永远不会被执行 . 我的AsyncTask永远不会完成,它会陷入无限循环?!但是看看 ZipInputStream.closeEntry()
的来源似乎没有任何循环或任何可疑的东西?
我也尝试使用 ZipFile
而不是 ZipInputStream
解压缩ZIP存档,但后来我收到以下错误:
java.util.zip.ZipException: End Of Central Directory signature not found
ZIP文件没有任何问题,我在Mac OSx上使用 zip -v -T
进行了测试 . 我也尝试使用ZIP版本3.0和2.1重新压缩它(原始版本为2.0) . 我可以在Mac OSx上解压缩所有版本而没有任何问题(使用Unarchiver和Archive Utility) .
这让我疯了,可能出现什么问题?
Update (solved)
原来是一个非常愚蠢的问题,与解压缩无关 .
我在解压缩之前从服务器下载ZIP文件,显然我忘记在开始解压缩操作之前在下载操作的输出流上调用 close()
.
也许这个主题可以帮助那些犯同样愚蠢错误的人 .
1 回答
好吧,即使您关闭所有以前的输出和输入流,有时您的ZIP提取代码也会卡住 . 并且,这是a known bug:
ZipInputStream#read
可以返回0 .Addition:
如果您的ZIP文件包含一些具有非ACSII文件名的文件,则'll face problem with extracting. Android' s
ZipInputStream
与UTF-8,CP437等不兼容 .在这种情况下,Apache Commons应该是一个解决方案: