繁体   English   中英

如何在创建之前估计java中的zip文件大小

[英]How to estimate zip file size in java before creating it

我有一个要求,我必须从可用文件列表中创建一个zip文件。 这些文件有不同的类型,如txt,pdf,xml等。我正在使用java util类来完成它。

这里的要求是保持最大文件大小为5 MB。 我应该根据时间戳从列表中选择文件,将文件添加到zip,直到zip文件大小达到5 mb。 我应该跳过剩下的文件。

请告诉我,如果在java中有一种方法,我可以提前估计zip文件大小而不创建实际文件?

或者有没有其他方法来处理这个问题

将ZipOutputStream包装到个性化的OutputStream中,命名为YourOutputStream。

  • YourOutputStream的构造函数将创建另一个ZipOutputStream (zos2),它包装一个新的ByteArrayOutputStream (baos)
    public YourOutputStream(ZipOutputStream zos, int maxSizeInBytes)
  • 当您想使用YourOutputStream编写文件时,它将首先在zos2上编写它
    public void writeFile(File file) throws ZipFileFullException
    public void writeFile(String path) throws ZipFileFullException
    等等...
  • 如果baos.size()maxSizeInBytes
    • 在zos1中写入文件
  • 其他
    • 关闭zos1,baos,zos2抛出异常。 对于异常,我想不出已经存在的异常,如果有,请使用它,否则创建自己的IOException ZipFileFullException。

您需要两个ZipOutputStream,一个要写在您的驱动器上,一个用于检查您的内容是否超过5MB。

编辑:事实上我检查过, 你不能轻易删除ZipEntry

http://download.oracle.com/javase/6/docs/api/java/io/ByteArrayOutputStream.html#size()

Colin Herbert的+1:逐个添加文件,要么备份上一步,要么删除最后一个文件(如果存档很大)。 我只是想补充一些细节:

预测太不可靠了。 例如,PDF可以包含未压缩的文本,并压缩到原始文本的30%,或者它包含已经压缩的文本和图像,压缩到80%。 您需要检查整个PDF的可压缩性,基本上必须压缩它们。

您可以尝试统计预测 ,但这可以减少尝试失败的次数,但您仍然需要实施上述建议。 首先使用更简单的实现,看看它是否足够。

或者,单独压缩文件 ,然后选择绑定在一起不超过5 MB的文件。 如果解压缩也是自动化的,您可以将zip文件绑定到单个未压缩的zip文件中。

也许你每次都可以添加一个文件,直到达到5MB的限制,然后丢弃最后一个文件。 @Gopi一样,我认为没有任何方法可以在不实际压缩文件的情况下估算它。

当然,文件大小不会增加(或者可能是一点,因为zip标题?),所以至少你有一个“最坏情况”估计。

只想分享我们如何实施手动方式

            int maxSizeForAllFiles = 70000; // Read from property
        int sizePerFile = 22000; // Red from property
        /**
         * Iterate all attachment list to verify if ZIP is required
         */
        for (String attachFile : inputAttachmentList) {
            File file = new File(attachFile);
            totalFileSize += file.length();
            /**
             * if ZIP required ??? based on the size
             */
            if (file.length() >= sizePerFile) {
                toBeZipped = true;
                logger.info("File: "
                            + attachFile
                                + " Size: "
                                + file.length()
                                + " File required to be zipped, MAX allowed per file: "
                                + sizePerFile);
                break;
            }
        }
        /**
         * Check if all attachments put together cross MAX_SIZE_FOR_ALL_FILES
         */
        if (totalFileSize >= maxSizeForAllFiles) {
            toBeZipped = true;
        }
        if (toBeZipped) {
            // Zip Here iterating all attachments
        }

我不认为有任何方法可以估计将创建的zip的大小,因为拉链被处理为流。 除非您实际压缩它,否则在技术上不可能预测创建的压缩格式的大小。

我在具有已知输入类型的项目上执行了一次。 我们知道一般来说我们的数据压缩在5:1左右(这是所有文本。)所以,我检查文件大小并除以5 ...

在这种情况下,这样做的目的是检查文件是否可能低于特定大小。 我们只需粗略估计。

总而言之,我注意到像7zip这样的zip应用程序会创建一个特定大小的zip文件(如CD),然后一旦达到限制就将zip拆分为新文件。 您可以查看该源代码。 我之前在代码中实际使用过该应用程序的命令行版本。 他们有一个你也可以使用的图书馆。 不知道与Java集成的程度如何。

为了它的价值,我还使用了一个名为SharpZipLib的库。 非常好。 我想知道是否有Java端口。

有一个更好的选择。 创建一个只计算写入字节的虚拟LengthOutputStream

public class LengthOutputStream extends OutputStream {

    private long length = 0L;

    @Override
    public void write(int b) throws IOException {
        length++;
    }

    public long getLength() {
        return length;
    }
}

您只需将LengthOutputStream连接到ZipOutputStream

public static long sizeOfZippedDirectory(File dir) throws FileNotFoundException, IOException {
        try (LengthOutputStream sos = new LengthOutputStream();
            ZipOutputStream zos = new ZipOutputStream(sos);) {
            ... // Add ZIP entries to the stream
            return sos.getLength();
        }
    }

LengthOutputStream对象计算压缩流的字节数但不存储任何内容,因此没有文件大小限制。 此方法提供准确的大小估计,但几乎与创建ZIP文件一样慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM