簡體   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