我无法使用ZipInputStream完全解压缩我的zip文件

时间:2014-01-20 15:42:16

标签: android zipinputstream

我有几个zip文件,每个文件都包含几个文件,我想用ZipInputStream类提取这些文件。其中有一些图片。当我尝试使用BufferedOutputStream提取这些图像时,它们会被部分解压缩并且图像不完整。

private void extractArchives() {

    ZipInputStream zis;

    File archiveDir = new File(
             Environment.getExternalStorageDirectory().getAbsolutePath() +
     "/archives/");

    File[] files = archiveDir.listFiles();

    for (int i = 0; i < files.length; ++i)
    {
        File file = files[i];

        try
        {
            zis = new ZipInputStream(new FileInputStream(file));
            ZipEntry ze;

            while ((ze = zis.getNextEntry()) != null)
            {
                BufferedOutputStream bos;
                byte[] buffer = new byte[102400];
                int count;

                while ((count = zis.read(buffer)) != -1)
                {
                    String fileName = ze.getName();

                    if (fileName.endsWith(".jpg"))
                    {
                        path += File.separator + fileName;
                        bos = new BufferedOutputStream(new FileOutputStream(path));
                        bos.write(buffer, 0, count);
                        bos.close();
                    }
                }
            }

            zis.close();

        }

        catch(FileNotFoundException e) { continue; }

        //If the file is not a zip file or is a directory
        catch (IOException e) { continue; }

    }
}

上面的代码有什么问题吗?使用BufferedOutputStream会导致此问题吗?我很欣赏任何想法。感谢。

2 个答案:

答案 0 :(得分:1)

我根据Erwin的说法修改了方法,现在它可以工作:

private void extractArchives() {

    File archiveDir = new File(
                Environment.getExternalStorageDirectory().getAbsolutePath() +
                "/archives/");

    String archivePath = archiveDir.getAbsolutePath();

    File[] files = archiveDir.listFiles();

    for (int i = 0; i < files.length; ++i)
    {
        File file = files[i];

        if(!file.isDirectory())
        {
            try {

                ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
                ZipEntry entry = zis.getNextEntry();

                while (entry != null)
                {
                    if(entry.getName().endsWith(".jpg"))
                    {
                        String imagePath = themePath + File.separator + entry.getName();

                        BufferedOutputStream bos = new BufferedOutputStream(
                                    new FileOutputStream(imagePath));

                        byte[] buffer = new byte[4096];

                        int read = 0;

                        while ((read = zis.read(buffer)) != -1) bos.write(buffer, 0, read);

                        imagePath = "";

                        bos.close();
                    }

                    zis.closeEntry();

                    entry = zis.getNextEntry();
                }

                zis.close();
            }

            catch (FileNotFoundException e) {}

            catch (IOException e) {}
        }
    }
}

答案 1 :(得分:0)

专注于遍历zip条目的循环,问题是您从zip条目读取最多102400个字节,然后将其写入新文件。如果将相同的图像文件写入新文件,则下一个最大102400个字节。如果路径名与旧文件相同,则会覆盖旧文件。但由于你经常附加到局部变量'path',我不确定数据的最终位置。

将FileOutputStream的开口拉出内部循环,并继续写入相同的OutputStream,直到您无法从当前ZipEntry读取更多字节。然后才转到下一个ZipEntry和下一个OutputStream。

这是在Java中读取和复制流的标准模式,因此我可以在不具有filespathzis定义的情况下修复代码,但如果您可以发布一个实际的编译代码示例,以便其他人也可以从中受益。

生产代码中需要的另一项改进是将bos.close()包装在try / finally块中,以便在从输入读取时出现异常时输出文件也会关闭。

        while ((ze = zis.getNextEntry()) != null) {
            String fileName = ze.getName();

            if (fileName.endsWith(".jpg")) {
                String filepath = path + File.separator + fileName;
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filepath));
                byte[] buffer = new byte[102400];
                int count;
                while ((count = zis.read(buffer)) != -1) {
                    bos.write(buffer, 0, count);
                }
                bos.close();
            }
        }