寵物集市-寵物集市華東、華南、華北排行榜一覽表
1516
2022-05-29
在java(JDK)中我們可以使用ZipOutputStream去創建zip壓縮文件,(參考我之前寫的文章 使用java API進行zip遞歸壓縮文件夾以及解壓 ),也可以使用GZIPOutputStream去創建gzip(gz)壓縮文件,但是java中沒有一種官方的API可以去創建tar.gz文件。所以我們需要使用到第三方庫Apache Commons Compress去創建.tar.gz文件。
在pom.xml中,我們可以通過如下的maven坐標引入commons-compress。
1
2
3
4
5
解釋說明
tar文件準確的說是打包文件,將文件打包到一個tar文件中,文件名后綴是.tar
Gzip是將文件的存儲空間壓縮保存,文件名后綴是.gz
tar.gz或.tgz通常是指將文件打包到一個tar文件中,并將它使用Gzip進行壓縮。
如果您閱讀完本文覺得對您有幫助的話,請給我一個贊,您的支持是我不竭的創作動力!
一、將兩個文件打包到tar.gz
下面的這個例子是將2個文件打包為tar.gz壓縮文件。下文代碼中的流操作使用了try-with-resources語法,所以不用寫代碼手動的close流。
import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; import org.junit.jupiter.api.Test; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; public class TarGzTest { @Test void testFilesTarGzip() throws IOException { //輸入文件,被壓縮文件 Path path1 = Paths.get("/home/test/file-a.xml"); Path path2 = Paths.get("/home/test/file-b.txt"); List
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
將file-a.xml和file-b.txt打包到output.tar文件中,并使用gzip對這個tar包進行壓縮??梢允褂萌缦旅畈榭磘ar包里面包含的文件。
$ tar -tvf /home/test/output.tar.gz -rw-r--r-- 0/0 23546 2020-08-17 12:07 file-a.xml -rw-r--r-- 0/0 34 2020-08-17 12:36 file-b.txt
1
2
3
二、將一個文件夾壓縮為tar.gz
下面的例子將一個文件夾,包含其子文件夾的文件或子目錄,打包為tar,并使用gzip進行壓縮。最終成為一個tar.gz打包壓縮文件。
其核心原理是:使用到Files.walkFileTree依次遍歷文件目錄樹中的文件,將其一個一個的添加到TarArchiveOutputStream.輸出流。
@Test void testDirTarGzip() throws IOException { // 被壓縮打包的文件夾 Path source = Paths.get("/home/test"); //如果不是文件夾拋出異常 if (!Files.isDirectory(source)) { throw new IOException("請指定一個文件夾"); } //壓縮之后的輸出文件名稱 String tarFileName = "/home/" + source.getFileName().toString() + ".tar.gz"; //OutputStream輸出流、BufferedOutputStream緩沖輸出流 //GzipCompressorOutputStream是gzip壓縮輸出流 //TarArchiveOutputStream打tar包輸出流(包含gzip壓縮輸出流) try (OutputStream fOut = Files.newOutputStream(Paths.get(tarFileName)); BufferedOutputStream buffOut = new BufferedOutputStream(fOut); GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(buffOut); TarArchiveOutputStream tOut = new TarArchiveOutputStream(gzOut)) { //遍歷文件目錄樹 Files.walkFileTree(source, new SimpleFileVisitor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
三、解壓tar.gz壓縮文件
下面一個例子說明如何解壓一個tar.gz文件,具體內容請看代碼注釋。
@Test void testDeCompressTarGzip() throws IOException { //解壓文件 Path source = Paths.get("/home/test/output.tar.gz"); //解壓到哪 Path target = Paths.get("/home/test2"); if (Files.notExists(source)) { throw new IOException("您要解壓的文件不存在"); } //InputStream輸入流,以下四個流將tar.gz讀取到內存并操作 //BufferedInputStream緩沖輸入流 //GzipCompressorInputStream解壓輸入流 //TarArchiveInputStream解tar包輸入流 try (InputStream fi = Files.newInputStream(source); BufferedInputStream bi = new BufferedInputStream(fi); GzipCompressorInputStream gzi = new GzipCompressorInputStream(bi); TarArchiveInputStream ti = new TarArchiveInputStream(gzi)) { ArchiveEntry entry; while ((entry = ti.getNextEntry()) != null) { //獲取解壓文件目錄,并判斷文件是否損壞 Path newPath = zipSlipProtect(entry, target); if (entry.isDirectory()) { //創建解壓文件目錄 Files.createDirectories(newPath); } else { //再次校驗解壓文件目錄是否存在 Path parent = newPath.getParent(); if (parent != null) { if (Files.notExists(parent)) { Files.createDirectories(parent); } } // 將解壓文件輸入到TarArchiveInputStream,輸出到磁盤newPath目錄 Files.copy(ti, newPath, StandardCopyOption.REPLACE_EXISTING); } } } } //判斷壓縮文件是否被損壞,并返回該文件的解壓目錄 private Path zipSlipProtect(ArchiveEntry entry,Path targetDir) throws IOException { Path targetDirResolved = targetDir.resolve(entry.getName()); Path normalizePath = targetDirResolved.normalize(); if (!normalizePath.startsWith(targetDir)) { throw new IOException("壓縮文件已被損壞: " + entry.getName()); } return normalizePath; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
API Java 彈性文件服務
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。