将Zip转换为Store压缩

时间:2013-12-28 03:46:47

标签: java android compression zip

我有一个压缩的zip文件file.zip。有没有办法更改要存储的文件的压缩级别(无压缩)。

我已经编写并尝试了以下代码并且它可以工作,但我将在内存和存储将受到限制并且可能没有足够空间的环境中运行它。我正在使用zip4j库。

此代码将输入zip提取到文件夹,然后使用存储压缩级别重新压缩它。这个问题在于,在执行的一个点上,存储器上有3个zip副本,这是一个问题,因为空间是一个限制。

try {
            String zip = "input.zip";
            final ZipFile zipFile = new ZipFile(zip);
            zipFile.extractAll("dir");
            File file = new File("dir");
            ZipParameters params = new ZipParameters();
            params.setCompressionMethod(Zip4jConstants.COMP_STORE);
            params.setIncludeRootFolder(false);

            ZipFile output = new ZipFile(new File("out.zip"));

            output.addFolder(file, params);
            file.delete();
            return "Done";
        } catch (Exception e) {
            e.printStackTrace();
            return "Error";
        }

那么有关另一种方法来解决这个问题的建议吗?或者对我当前的代码进行一些速度或内存优化?

2 个答案:

答案 0 :(得分:1)

作为替代方案,我们可以在内存中逐个读取zip文件或者在临时文件中读取文件,例如

    ZipInputStream is = ...
    ZipOutputStream os = ...
    os.setMethod(ZipOutputStream.STORED);
    int bSize = ... calculate max available size 
    byte[] buf = new byte[bSize];
    for (ZipEntry e; (e = is.getNextEntry()) != null;) {
        ZipEntry e2 = new ZipEntry(e.getName());
        e2.setMethod(ZipEntry.STORED);
        int n = is.read(buf);
        if (is.read() == -1) {
            // in memory
            e2.setSize(n);
            e2.setCompressedSize(n);
            CRC32 crc = new CRC32();
            crc.update(buf, 0, n);
            e2.setCrc(crc.getValue());
            os.putNextEntry(e2);
            os.write(buf, 0, n);
            is.closeEntry();
            os.closeEntry();
        } else {
            // use tmp file
        }
    }

内存中的读取应该更快

答案 1 :(得分:0)

几个小时后,我终于通过玩输入流来获得它。

try {
            final ZipFile zipFile = new ZipFile("input.zip");
            File output = new File("out.zip");
            byte[] read = new byte[1024];
            ZipInputStream zis = new ZipInputStream(new FileInputStream(zip));
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(output));
            ZipEntry ze;
            zos.setLevel(ZipOutputStream.STORED);
            zos.setMethod(ZipOutputStream.STORED);
            while((ze = zis.getNextEntry()) != null) {
                int l;
                zos.putNextEntry(ze);
                System.out.println("WRITING:  " + ze.getName());
                while((l = zis.read(read)) > 0) {
                    zos.write(read, 0, l);
                }
                zos.closeEntry();
            }
            zis.close();
            zos.close();
            return "Done";
        } catch (Exception e) {
            e.printStackTrace();
            return "Error";
        }

非常感谢你的回答Evgeniy Dorofeev,当我读你的时,我真的得到了答案!但是,我更喜欢我的方法,因为它在内存中最多只占用1 MB(我是对的吗?)。此外,我尝试执行您的代码,只传输输入zip中的第一个文件。