当前位置: 首页 > 知识库问答 >
问题:

用ZipInputStream解压缩永远不会完成

苏承载
2023-03-14
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;
    }

}

我还尝试使用zipfile而不是zipputstream提取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实用程序)。

这快把我逼疯了,可能会有什么错?

我在解压压缩文件之前从服务器下载这些压缩文件,显然我忘记在开始解压操作之前调用下载操作的输出流的close()

也许这条线可以帮助其他犯同样愚蠢错误的人。

共有1个答案

姜卜霸
2023-03-14

有时候,即使关闭以前所有的输出和输入流,您的ZIP提取代码也会被卡住。而且,这是一个已知的bug:zipinputstream#read可以返回0。

添加:

如果您的ZIP文件包含一些非ACSII文件名的文件,您将面临解压问题。Android的zipinputstream不能很好地与UTF-8、CP437等一起工作。

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;
}
 类似资料:
  • 我正在学习Java8以及更多关于“可完成的未来”的细节。以下是有趣的教程:https://www.callicoder.com/java-8-completablefuture-tutorial/ 我编写了以下Java类: (为了运行该代码,您需要resteasy-Client库) 但是我不明白为什么即使收集了所有的响应,主方法也不会终止... 我错过什么了吗?是否有一些“完整”的方法可以在任何地

  • 1)我的plist配置提供背景模式: 2) 在中,我有: 3) 我在委托中声明了协议。 4)我实现了以下方法,但它永远不会被触发。(只有当我用“XCode-”模拟获取时才有效 为什么?这是DP5测试错误吗?我应该雷达这个吗?

  • 问题内容: 看过很多论坛,但没有找到答案…简单的东西,用@PostLoad注释的方法永远不会被调用…通过@EntityListeners添加了侦听器,但问题仍然存在。我正在使用基于SessionFactory的配置。 问题答案: 当使用基于基础的配置时,EJB3 注释不起作用,后期加载方法将永远不会被调用。 使用Hibernate的Interceptor或事件或基于基本的配置。

  • 问题内容: 我知道这是一项容易的任务,但是更改代码后它停止工作,并且无法恢复!我实际上使用了两个函数来进行压缩和解压缩,尽管实际上它是“ jar”和“ unjar”,但这并没有太大的区别 任何帮助/建议吗? 创建JarFile时发生错误: 问题答案: 我不知道这是否是您的问题,但是通常最好在完成写入后关闭每个zip条目。 请参阅。 在显示的代码中,不会关闭邮政编码中的最后一个条目。您也不会显示关闭

  • 我正在为一个简单的Spring Boot应用程序编写Kafka联调。该应用程序简单地发布到Kafka主题。 我正在使用一个嵌入式Kafka实例进行测试。当通过Intellij运行时,测试运行得非常好,但当我通过gradle运行时,测试失败。看起来好像倒计时从未达到0,测试最终超时。 生产者配置: 制片人: 消费者: 测试: application.yml: 知道问题出在哪里吗?

  • 我在测试一些短信发送和接收结果应用程序。它按预期发送短信,并祝酒“短信发送”。但它从不祝酒“短信发送”。它也从来没有达到 这意味着从不需要为结果SMS_DELIVERED...知道为什么吗?... Androidanifest.xml