java 7zip解压_Apache Commons Compress介绍-JAVA压缩解压7z文件
7zip(下面簡稱7z)是由Igor Pavlov所開發(fā)的一種壓縮格式,主要使用的壓縮算法是LZMA/LZMA2。7z是一種壓縮比非常高的格式,這與其壓縮算法LZMA有直接關(guān)系,所以很多大文件都是用7z進行壓縮的,比如游戲之類;高壓縮比并非只有好處,就是7z的壓縮速度非常慢(解壓速度尚可)-當然,所有壓縮算法都類似:高壓縮比往往是解壓速度慢,這實際上可以理解為CPU與內(nèi)存/硬盤之間的trade off,后面我會詳細聊一下壓縮背后的原理與算法。
Commons Compress是少數(shù)支持7z壓縮/解壓的JAVA庫(據(jù)我所知除了Commons Compress就只有XZ Utils了),其API也相對友好。
與zip格式不同,commons compress在解壓7z時只提供了SevenZFile類,并未提供SevenZInputStream進行逐個解壓的接口,這與7z文件的格式、算法都有關(guān)系,這里不再展開說明了。
好了,廢話不多說,我們進入主題:
查看7z中的所有文件
我們可以通過sevenZFile.getEntries()查看7z中的所有文件,包括文件名等屬性都可以在SevenZArchiveEntry中查看。相關(guān)代碼如下:
SevenZFile sevenZFile = new SevenZFile(new File("/root/test.7zip"));
final Iterable entries = sevenZFile.getEntries();
for (SevenZArchiveEntry entry : entries) {
System.out.println(entry.getName());
System.out.println(entry.getCompressedSize()); // 文件壓縮后大小 System.out.println(entry.getSize()); // 文件大小}
解壓全部文件
解壓全部文件時可以通過sevenZFile.getNextEntry遍歷所有文件并進行解壓,比如我要將位于/root/test.7zip位置的文件,全部解壓到/tmp/output目錄下,代碼如下:
try (SevenZFile sevenZFile = new SevenZFile(new File("/root/test.7zip"))) {
byte[] buffer = new byte[4096];
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null) {
if (entry.isDirectory()) {
continue;
}
File outputFile = new File("/tmp/output/" + entry.getName());
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
while (sevenZFile.read(buffer) > 0) {
fos.write(buffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
解壓特定文件
可以通過sevenZFile.getEntries(),獲得所有文件后,通過遍歷找到需要解壓的zip文件,調(diào)用SevenZFile.getInputStream獲取其InputStream,進行解壓,比如需要將/root/test.7zip壓縮包中,文件名為targetFile的文件,解壓到/tmp/output/targetFile文件中,代碼如下:
SevenZFile sevenZFile = new SevenZFile(new File("/root/test.7zip"));
final Iterable entries = sevenZFile.getEntries();
InputStream inputStream = null;
for (SevenZArchiveEntry entry : entries) {
if (entry.getName().equals("targetFile")) {
inputStream = sevenZFile.getInputStream(entry);
}
}
// 讀取input stream即可完成解壓byte[] buffer = new byte[4096];
File outputFile = new File("/tmp/output/targetFile");
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
while (inputStream.read(buffer) > 0) {
fos.write(buffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
注意:7z解壓特定文件(也叫隨機訪問)是Compress的1.20版本以后才支持的特性
解壓內(nèi)存中的文件
Compress的所有壓縮,都可以處理硬盤及內(nèi)存中的文件,7z也不例外,這在網(wǎng)絡(luò)IO等場景下非常實用,使用也很簡單:
// 通過網(wǎng)絡(luò)IO或其他途徑,將7z文件讀入內(nèi)存byte[] data = XXX
SevenZFile sevenZFile = new SevenZFile(new SeekableInMemoryByteChannel(data));
注意:如果文件較大時,讀入內(nèi)存可能消耗很多內(nèi)存資源
解壓分卷7z文件
分卷文件解壓也十分簡單:
SevenZFile sevenZFile = new SevenZFile(MultiReadOnlySeekableByteChannel
.forFiles(new File("/root/test.7z.001"), new File("/root/test.7z.002")));
// 剩余代碼類似XXX
注意:傳入MultiReadOnlySeekableByteChannel.forFiles的7z分卷文件,需要按照正確的順序排列
壓縮
Compress壓縮7z文件,是通過xz utils實現(xiàn)的,并且xz在Compress的POM中是可選依賴,因此,如果要使用Compress壓縮7z文件,需要在POM中手動依賴xz utils
org.tukaani
xz
1.8
壓縮功能相對解壓,沒有那么多選擇,具體可以參見下面代碼中的注釋:
File dir = new File("/root/dir");
File output = new File(dir, "test.7z");
final Date accessDate = new Date();
final Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, -1);
final Date creationDate = cal.getTime();
try (SevenZOutputFile outArchive = new SevenZOutputFile(output)) {
// 在7z中創(chuàng)建一個文件夾 SevenZArchiveEntry entry = outArchive.createArchiveEntry(dir, "foo/");
outArchive.putArchiveEntry(entry);
outArchive.closeArchiveEntry();
// 創(chuàng)建一個新的文件entry entry = new SevenZArchiveEntry();
// 文件命名 entry.setName("foo/bar");
// 文件創(chuàng)建時間、最后修改時間 entry.setCreationDate(creationDate);
entry.setAccessDate(accessDate);
outArchive.putArchiveEntry(entry);
// 這里是文件要寫入的數(shù)據(jù),可能是從其他文件中讀取到的,也可以自己操作 byte[] data = XXX
outArchive.write(new byte[0]);
outArchive.closeArchiveEntry();
// 寫入第二個文件,與第一個類似 entry = new SevenZArchiveEntry();
entry.setName("xyzzy");
outArchive.putArchiveEntry(entry);
outArchive.write(0);
outArchive.closeArchiveEntry();
// 完成7z文件寫入后,需要調(diào)用finish outArchive.finish();
}
總結(jié)
以上就是Commons Compress處理7z格式的常用接口,同樣的,如果使用中遇到了什么問題或bug,歡迎到Compress的JIRA上提問題,當然也是需要用英語提問的:)- ASF JIRA?issues.apache.org
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的java 7zip解压_Apache Commons Compress介绍-JAVA压缩解压7z文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java c3p0 配置文件_【c3p0
- 下一篇: 蛇果为什么叫蛇果?