[英]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。
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
您需要兩個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.