Go语言tar归档文件的读写操作
2023-06-13 09:19:41 时间
在上一节《创建 .zip 归档文件》中我们介绍了 zip 归档文件的创建和读取,那么接下来介绍一下 tar 归档文件的创建及读取。
![Go语言tar归档文件的读写操作](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/15/20210715_60f02ea016ddb.gif)
图:生成的 output.tar 文件
![Go语言tar归档文件的读写操作](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/15/20210715_60f02ea03d1cd.gif)
图:解压 tar 包
创建 tar 归档文件
tar 是一种打包格式,但不对文件进行压缩,所以打包后的文档一般远远大于 zip 和 tar.gz,因为不需要压缩的原因,所以打包的速度是非常快的,打包时 CPU 占用率也很低。
tar 的目的在于方便文件的管理,比如在我们的生活中,有很多小物品分散在房间的各个角落,为了方便整洁可以将这些零散的物品整理进一个箱子中,而 tar 的功能就类似这样。
创建 tar 归档文件与创建 .zip 归档文件非常类似,主要不同点在于我们将所有数据都写入相同的 writer 中,并且在写入文件的数据之前必须写入完整的头部,而非仅仅是一个文件名。
tar 打包实现原理如下:
- 创建一个文件 x.tar,然后向 x.tar 写入 tar 头部信息;
- 打开要被 tar 的文件,向 x.tar 写入头部信息,然后向 x.tar 写入文件信息;
- 当有多个文件需要被 tar 时,重复第二步直到所有文件都被写入到 x.tar 中;
- 关闭 x.tar,完成打包。
下面通过示例程序简单演示一下Go语言 tar 打包的实现:
package main import ( "archive/tar" "fmt" "io" "os" ) func main() { f, err := os.Create("./output.tar") //创建一个 tar 文件 if err != nil { fmt.Println(err) return } defer f.Close() tw := tar.NewWriter(f) defer tw.Close() fileinfo, err := os.Stat("./main.exe") //获取文件相关信息 if err != nil { fmt.Println(err) } hdr, err := tar.FileInfoHeader(fileinfo, "") if err != nil { fmt.Println(err) } err = tw.WriteHeader(hdr) //写入头文件信息 if err != nil { fmt.Println(err) } f1, err := os.Open("./main.exe") if err != nil { fmt.Println(err) return } m, err := io.Copy(tw, f1) //将main.exe文件中的信息写入压缩包中 if err != nil { fmt.Println(err) } fmt.Println(m) }
运行上面的代码会在当前目录下生成一个 output.tar 文件,如下图所示:
![Go语言tar归档文件的读写操作](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/15/20210715_60f02ea016ddb.gif)
图:生成的 output.tar 文件
解压 tar 归档文件
解压 tar 归档文件比创建 tar 归档文档稍微简单些。首先需要将其打开,然后从这个 tar 头部中循环读取存储在这个归档文件内的文件头信息,从这个文件头里读取文件名,以这个文件名创建文件,然后向这个文件里写入数据即可。
示例代码如下所示:
package main import ( "archive/tar" "fmt" "io" "os" ) func main() { f, err := os.Open("output.tar") if err != nil { fmt.Println("文件打开失败", err) return } defer f.Close() r := tar.NewReader(f) for hdr, err := r.Next(); err != io.EOF; hdr, err = r.Next() { if err != nil { fmt.Println(err) return } fileinfo := hdr.FileInfo() fmt.Println(fileinfo.Name()) f, err := os.Create("123" + fileinfo.Name()) if err != nil { fmt.Println(err) } defer f.Close() _, err = io.Copy(f, r) if err != nil { fmt.Println(err) } } }
运行上面的程序会将 tar 包的文件解压到当前目录中,如下图所示:
![Go语言tar归档文件的读写操作](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/15/20210715_60f02ea03d1cd.gif)
图:解压 tar 包
至此,我们完成了对压缩和归档文件及常规文件处理的介绍。Go语言使用 io.Reader、io.ReadCloser、io.Writer 和 io.WriteCloser 等接口处理文件的方式让开发者可以使用相同的编码模式来读写文件或者其他流(如网络流或者甚至是字符串),从而大大降低了难度。
相关文章
- 2022-08-21:以下go语言代码输出什么?A:0;B:panic;C:不知道。 package main var n = -99 func main()
- Golang语言(打卡第三天)map、递归、报错和练习题|Go主题月
- 2022-08-05:以下go语言代码输出什么?A:65, string;B:A, string;C:65, int;D:报错。
- 2022-10-02:以下go语言代码能否通过编译?A: 能;B: 不能;C: 不知道。package mainimport (
- Go复合数据类型数组和切片
- 「Go工具箱」推荐一个简单、实用的图像处理工具:imaging
- 「Go工具箱」go语言csrf库的使用方式和实现原理
- Go语言基准测试(benchmark)三部曲之二:内存篇
- Go 语言 Web 应用怎么使用 Nginx 部署?
- Go 模块 verifying xxx/go.mod: checksum mismatch 问题处理
- 我在使用 Go 过程中犯过的低级错误
- Go-包管理-go install
- 精通Go语言开发Redis应用(go语言redis开发)
- Go语言环境配置:在 Linux 下实现(go环境搭建linux)
- 如何在Linux上安装Go语言?——简单易懂的指南(linux安装go语言)
- MySQL中使用Go语言的好处(mysql中go什么)
- 使用Go语言实现Redis数据库(用go实现redis)
- 用Go语言深入Redis缓存技术(用go写redis)
- Go语言操作Oracle轻松实现数据库编程(go语言访问oracle)
- 前行不止Go语言监听Oracle日志(go监听oracle日志)
- 数据库Go语言实现监控Oracle数据库(go监听oracle)
- ODBC数据驱动程序连接Oracle数据库Go语言之旅(go使用oracle)
- Go语言开发协程与Redis的结合使用(协程redis详细解说)