前言
近来有个需求,需要从 zip
中提取一个文件出来,因为只用到其中的一个,其它的用不到,如果全部提取出来就有点多余了,在经过一番摸索发现还真可以。
实现
Go
标准库里有 archive/zip
这个包,所以我们可以直接使用
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
|
import (
"archive/zip"
"io"
"log"
"os"
)
func main() {
f, err := zip.OpenReader("test.zip") // 打开zip文件
if err != nil {
log.Println("open zip err: ", err)
return
}
defer f.Close()
testFile, err := f.Open("test.txt") // 打开zip中的test.txt,这里需要使用相对路径,如果你打开的是 test下的text.txt,则这里要传入 test/test.txt
if err != nil {
log.Println("open test.txt err: ", err)
return
}
defer testFile.Close()
dst, err := os.Create("test.txt") // 创建一个文件用来存放解压出来的内容
defer dst.Close()
_, err = io.Copy(dst, testFile) // 把内容复制到目标文件中
if err != nil {
log.Println("提取 test.txt失败: ", err)
return
}
log.Println("提取 test.txt成功")
}
|
提取一个文件的步骤
- 使用
zip.OpenReader
打卡一个 zip
文件
- 然后使用
Open
打开 zip
中的文件
- 把内容拷贝出来
提取所有压缩文件
讲了提取 zip
中的一个文件,顺便给出提取所有文件的版本。
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
|
import (
"archive/zip"
"io"
"log"
"os"
"path/filepath"
)
func main() {
r, err := zip.OpenReader("test.zip")
if err != nil {
log.Fatal(err)
}
defer r.Close()
for _, f := range r.File {
if f.FileInfo().IsDir() {
os.MkdirAll(f.Name, os.ModePerm)
} else {
if err = os.MkdirAll(filepath.Dir(f.Name), os.ModePerm); err != nil {
log.Fatalln("mkdir failed:", f.Name, err)
return
}
zf, err := f.Open()
if err != nil {
log.Fatalln("open zip file", f.Name, "failed")
return
}
defer zf.Close()
outFile, err := os.OpenFile(f.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
log.Fatalln("create file", f.Name, "failed")
return
}
defer outFile.Close()
_, err = io.Copy(outFile, zf)
if err != nil {
log.Fatalln("copy failed ", err)
return
}
}
}
}
|
总结
go
语言实现解压的功能还是非常简单的,标准库就提供了解压的功能。
参考