2012-11-15 39 views
4

我的情況是,我有一個zip文件,其中包含一些文件(txt,png,...),我想直接讀取它們的名稱,我測試了下面的代碼,但沒有結果(NullPointerExcepion):直接讀取Zip文件中的文件 - Java

InputStream in = Main.class.getResourceAsStream("/resouces/zipfile/test.txt"); 
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); 

資源是一個包,並zip文件是zip文件。

+0

是的,這絕對不會工作。 – Perception

+1

你需要java.util.zip http://docs.oracle.com/javase/6/docs/api/java/util/zip/package-summary.html – gefei

+1

是類路徑上的zip文件嗎?它需要是 – chrislhardin

回答

14

如果你能確保你的zip文件將永遠不會被包裝的另一個罐子裏面,你可以使用類似:

URL zipUrl = Main.class.getResource("/resources/zipfile.zip"); 
URL entryUrl = new URL("jar:" + zipUrl + "!/test.txt"); 
InputStream is = entryUrl.openStream(); 

或者:

URL zipUrl = Main.class.getResource("/resources/zipfile.zip"); 
File zipFile = new File(zipUrl.toURI()); 
ZipFile zip = new ZipFile(zipFile); 
InputStream is = zip.getInputStream(zip.getEntry("test.txt")); 

否則,你的選擇是:

  • 對於需要加載的每個條目,使用ZipInputStream掃描一次zip文件。如果你有很多資源,這可能會很慢,除非你可以爲你的所有資源重複使用相同的ZipInputStream。
  • 不要將資源打包在一個嵌套的zip文件中,只要將它們與代碼一起插入jar中即可。
  • 將嵌套的zip文件複製到臨時目錄中,並使用ZipFile類訪問它。
+2

+1,使用ZipFile類獲得當時直接輸入比掃描整個流更有效率。 – Perception

+0

你能解釋一下你的第一行嗎?(如果你可以......) – Adil

+0

當然可以。如果包含資源的zip文件包含在jar中,代碼示例將不起作用。我的意思是,zip文件必須是文件系統上的真實文件,而不是JAR條目。 –

3

你目前的做法絕對不行。你制定了一個任意的「訪問」方案,並在一個不知道你想要做什麼的類中使用它。你可以做的是使用一個ZipInputStream讀你正在尋找的條目:

URL zipFileURL = Thread.currentThread().getContextClassLoader().getResource("zipfile.zip"); 
InputStream inputStream = zipFileURL.openStream(); 
ZipInputStream zipInputStream = new ZipInputStream(inputStream); 

ZipEntry zipEntry = null; 

do { 
    zipEntry = zipInputStream.getNextEntry(); 
    if(zipEntry == null) break; 
} 
while(zipEntry != null && (! "textfile".equals(zipEntry.getName())); 

if(zipEntry != null) { 
    // do some stuff 
} 

這是即興代碼,修復它,做你所需要的。另外,可能會有一些更高效的類來處理Zip文件,例如在Apache Commons IO庫中。

0

zip文件中test.txt的路徑是什麼?您需要使用zip文件中的路徑來讀取此文件。還要確保你的zipfile在類路徑中。事實上,你可以將它捆綁在一個jar文件中。