2016-11-27 55 views
1

我可以通過與new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8)獲得文本文件。如果文件位於zip文件中的文件夾中,如何獲得相同的結果?我知道我可以將zip作爲ZipFile,將文件夾作爲ZipEntry,但我不清楚我如何獲取文件,也不知道如何將String排除在外。我不想創建任何文件或文件夾來獲取它。在java中獲取zip文件夾中的文件作爲字符串

編輯:每DPR的答案,這是我使用的:

String fileAsString; 
try (ZipFile zip = new ZipFile(path)) { 
    ZipEntry entry = zip.getEntry("folder/file.txt"); 
    if (entry == null) entry = zip.getEntry("folder\\file.txt"); 
    try (InputStream is = zip.getInputStream(entry)) { 
     try (Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A")) { 
      fileAsString = s.hasNext() ? s.next() : ""; 
     } 
    } 
} 
+4

你可以做一些像zipFile.getInputStream(zipEntry) –

+0

你錯過了在'(entry == null)'if語句中分配條目。如果使用反斜線,你的代碼將拋出一個'NullPointerException'。 – dpr

回答

1

技術上不存在這樣的東西作爲一個zip文件中的目錄。 Zip文件中的所有內容基本上都是條目(Java中的ZipEntry)。如果當前條目代表壓縮文件系統結構的目錄或常規文件,則可以使用isDirectory方法來確定。 ZipEntry的名稱屬性始終反映原始壓縮文件相對於存檔根目錄的完整目錄層次結構。這是一個文件Data\Folder1\example.txt你將在你的zip文件中有3 ZipEntries。一個用於Data,1個Data\Folder1和一個Data\Folder1\example.txt

只需遍歷ZipFileZipEntries並匹配所需文件的路徑和文件名,就可以輕鬆找到所需的條目。該條目的內容可以使用已經建議的ZipFile.getInputStream(ZipEntry)方法提取。

有關如何將InputStream讀取爲字符串的示例,請參閱this questions and the answers

使用Apache的commons-IO(IOUtils)用於讀取InputStream字符串這可能是這個樣子:

public String getFileContentsAsString(final File pZipFile, final String pFileName) throws Exception { 

    try (ZipFile zipFile = new ZipFile(pZipFile)) { 
     Enumeration<? extends ZipEntry> entries = zipFile.entries(); 
     while (entries.hasMoreElements()) { 
      ZipEntry currentEntry = entries.nextElement(); 
      if (matchesDesiredFile(pFileName, currentEntry)) { 
       try (InputStream entryIn = zipFile.getInputStream(currentEntry)) { 
        String text = IOUtils.toString(entryIn, Charsets.UTF_8); 
        return text; 
       } 
      } 
     } 
    } 

    return null; 
} 

private boolean matchesDesiredFile(final String pFileName, final ZipEntry pZipEntry) { 
    return !pZipEntry.isDirectory() && pZipEntry.getName().equals(pFileName); 
} 

如果你只是對條目的名稱屬性相匹配,你當然可以以及使用

ZipEntry zipEntry = zipFile.getEntry(filePathWithinZipArchive); 

獲得所需條目而不是迭代條目「手動」。

請注意,您應該仔細檢查用於目錄的分隔符。正如here指出的那樣,創建壓縮文件的應用程序可以使用\(反斜槓)或/(正斜槓)作爲目錄分隔符。我在Mac上使用zip終端命令嘗試了這一點,並且ZipEntry的名稱和原始文件名都是Data/Folder1/example.txt。如果使用其他工具創建zip,則ZipEntry的名稱可能爲Data\Folder1\example.txt。即使是混合變體(一個ZipEntry使用forward-,另一個使用反斜槓)也是可能的。如果您無法控制zip創建過程,您可能需要考慮這一點。

+0

謝謝!我在Windows中做過,而'ZipEntry'的名字是'folder/file.txt'。它可能與平臺無關。 – Blrp

+1

它似乎取決於用於創建zip文件的客戶端。不在平臺上......好的客戶端會使用正斜槓,而不是很好,曾經可能會使用反斜槓(請參見[這個問題和答案])(http://stackoverflow.com/questions/13846000/file-separators -of-路徑名稱的-的ZipEntry))。但是,如果您無法控制正在處理的壓縮文件的創建過程,則需要支持這兩種變體(即使是混合變體也是如此)。 – dpr

+0

我相應地更新了我的答案 – dpr

相關問題