2014-01-24 55 views
1

我有下面的代碼,在一個zip寫入一個文本文件:的java:變化的ZipEntry名

FileOutputStream fOut = new FileOutputStream(fullFilename, false); 
BufferedOutputStream bOut = new BufferedOutputStream(fOut); 
ZipOutputStream zOut = new ZipOutputStream(bOut); 

zOut.putNextEntry(new ZipEntry("aFile1.txt")); 
//Do some processing and write to zOut... 
zOut.write(...); 
(...) 
zOut.closeEntry(); 

zOut.close(); 
//Etc (close all resources) 

我需要去改變它已被寫入後的ZipEntry的文件名(如它的名字將取決於在其內容寫)。

此外,只有在知道最終文件名時(因爲文件大小可能非常大:沒有足夠的內存),它不是寫入緩衝區並寫入文件的選項。

任何意見如何做到這一點將不勝感激!

感謝, 托馬斯

回答

2

這是一個缺少的功能,可能很簡單,因爲條目本身沒有被壓縮。

要求重寫的最簡單方法是zip FileSystem:因爲Java 7可以使用zip文件作爲虛擬文件系統:寫入,重命名和移動文件。一個example。您將文件從普通文件系統複製到zip文件系統,然後在zip中重命名該文件。

// Create the zip file: 
URI zipURI = URI.create("jar:file:" + fullFilename); // "jar:file:/.../... .zip" 
Map<String, Object> env = new HashMap<>(); 
env.put("create", "true"); 
FileSystem zipFS = FileSystems.newFileSystem(zipURI, env, null); 

// Write to aFile1.txt: 
Path pathInZipfile = zipFS.getPath("/aFile1.txt"); 
BufferedWriter out = Files.newBufferedWriter(pathInZipfile, 
     StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW); 
out.write("Press any key, except both shift keys\n"); 
out.close(); 

// Rename file: 
Path pathInZipfile2 = zipFS.getPath("/aFile2.txt"); 
Files.move(pathInZipfile, pathInZipfile2); 

zipFS.close(); 

原則上,你也可以保留你的舊代碼 - 無需重命名。並使用一個zip文件系統來重命名。

+0

這並不簡單,因爲條目名稱是本地文件頭的一部分,必須在壓縮數據之前將其寫入輸出流。我想如果你有一個可尋址的流作爲底層的目的地,你可以想象回去修改標題來改變它的名字,但只有當新名字的字節數與舊字節的字節數完全相同時...... –

+0

@IanRoberts您將它帶到了一個地步:在Java的FileOutputStream中缺少一個隨機訪問查找並且指示文件位置丟失。但是zip格式很簡單,可以使用RandomAccessFile製作一個可修改的zip條目列表。 –

0

如何節省aFile1.txt內容到磁盤上的臨時文件,重命名,然後事後創建的zip文件?最後一步可以刪除您在磁盤上創建的文件。