作者: zyl910 一、緣由 現在zip類的文件越來越多了,例如jar、docx。 有時我們需批量處理這些文件中的數據,若都是手工操作的話就太麻煩了。於是考慮編程自動處理。 Java提供了ZipInputStream等zip的操作類。但是有些內容比較抽象,沒有代碼範例的話有點難以理解。例如zip中 ...
作者: zyl910
一、緣由
現在zip類的文件越來越多了,例如jar、docx。
有時我們需批量處理這些文件中的數據,若都是手工操作的話就太麻煩了。於是考慮編程自動處理。
Java提供了ZipInputStream等zip的操作類。但是有些內容比較抽象,沒有代碼範例的話有點難以理解。例如zip中的目錄究竟是什麼。
於是我做個個Demo來演示如何用它來解析zip文件,輸出信息。
二、源碼
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipReadTest {
public static void main(String[] args) {
String srcPath = "target/classes/static/test.docx";
try(FileInputStream is = new FileInputStream(srcPath)) {
run(System.out, is);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("ZipReadTest done.");
}
private static void run(PrintStream out, InputStream is) throws IOException {
try(ZipInputStream zis = new ZipInputStream(is)) {
ZipEntry zipEntry;
while ((zipEntry = zis.getNextEntry()) != null) {
if (null==zipEntry) continue;
String line = String.format("ZipEntry(%s, isDirectory=%d, size=%d, compressedSize=%d, time=%d, crc=%d, method=%d, comment=%s)",
zipEntry.getName(), (zipEntry.isDirectory())?1:0, zipEntry.getSize(), zipEntry.getCompressedSize(), zipEntry.getTime(), zipEntry.getCrc(), zipEntry.getMethod(), zipEntry.getComment());
out.println(line);
}
}
}
}
三、測試結果
對一個docx文件進行處理,測試結果如下:
ZipEntry([Content_Types].xml, isDirectory=0, size=1344, compressedSize=354, time=312739200000, crc=1239027019, method=8, comment=null)
ZipEntry(docProps/app.xml, isDirectory=0, size=289, compressedSize=183, time=312739200000, crc=4091958464, method=8, comment=null)
ZipEntry(docProps/core.xml, isDirectory=0, size=392, compressedSize=220, time=312739200000, crc=3065131828, method=8, comment=null)
ZipEntry(word/document.xml, isDirectory=0, size=36724, compressedSize=4017, time=312739200000, crc=1830572178, method=8, comment=null)
ZipEntry(word/fontTable.xml, isDirectory=0, size=2120, compressedSize=398, time=312739200000, crc=268271083, method=8, comment=null)
ZipEntry(word/numbering.xml, isDirectory=0, size=2868, compressedSize=502, time=312739200000, crc=3349595521, method=8, comment=null)
ZipEntry(word/settings.xml, isDirectory=0, size=815, compressedSize=325, time=312739200000, crc=773262145, method=8, comment=null)
ZipEntry(word/styles.xml, isDirectory=0, size=8628, compressedSize=1319, time=312739200000, crc=2957985579, method=8, comment=null)
ZipEntry(_rels/.rels, isDirectory=0, size=588, compressedSize=228, time=312739200000, crc=1578830051, method=8, comment=null)
ZipEntry(word/media/image1.emf, isDirectory=0, size=881176, compressedSize=97920, time=312739200000, crc=1974652776, method=8, comment=null)
ZipEntry(word/_rels/document.xml.rels, isDirectory=0, size=980, compressedSize=283, time=312739200000, crc=2086150245, method=8, comment=null)
ZipReadTest done.
以上就是docx內的文件結構。
平時使用WinZip等文件來查看zip類文件時,是顯示為樹形結構。但是在zip文件中實際上記錄的是相對路徑。
zip文件類一般不用記錄目錄,只記錄相對路徑就行。
當需要記錄目錄時,ZipEntry的name以分隔符結尾(如 word/
),相關數據流為空。
參考文獻
- Javadoc《Class ZipInputStream》. https://docs.oracle.com/javase/8/docs/api/index.html?java/util/zip/ZipInputStream.html