[Go 入门] 第二十章 处理文件
Go 入门系列参考于互联网资料与 人民邮电出版社 《Go 语言入门经典》 与 《Effective Go》,编写目的在于学习交流,如有侵权,请联系删除
本文内容:
文件的重要性
文件能够让程序员管理配置、储存程序的状态乃至从底层操作系统中读取数据
UNIX 型操作系统 (Linux 和 macOS)的一个重要特征就是,将一切视为文件。这意味着操作系统看来,从键盘到打印机的所有东西都可像文件那样编址。在这方面,UNIX 走的更远,它通过虚拟文件系统来暴露系统信息。
在 UNIX 系统中,可使用命令 cat
来读取文件的内容并将其打印到终端。/proc/loadavg 就是一个有关系统当前负载的虚拟文件
1 |
|
再次执行,会发现输出的数值发生了变化,代表了有关系统负载的数据是实时的
1 |
|
在大多数 UNIX 系统中,可试用命令 watch
来创建有关系统负载的实时视图,这个视图每隔 2s 更新一次
1 |
|
使用 ioutil 包读写文件
鉴于处理文件是一种常见的任务,标准库提供了 ioutil
包,可执行包含以下操作:
- 读取文件
- 列出目录的内容
- 创建临时目录
- 创建临时文件
- 创建文件
- 写入文件
读取文件
ioutil
包提供了函数 Readfile
,可使用它来完成这项任务,这个函数将一个文件路径作为参数,并以字节切片的方式返回文件的内容
1 |
|
创建文件
ioutil
包还提供了函数 WriteFile
。这个函数用于将数据写入文件,但也可使用它来创建文件。接收一个文件路径,要写入的数据,以及应用于文件的权限
文件权限是由 UNIX 权限衍生而来的,它们对应3类用户:文件所有者、与文件位于同一组的用户、其他用户
Go 语言使用 UNIX 权限的数字表示法,很多用于处理文件的函数都将权限值作为参数
文件权限:
符号表示法 | 数字表示法 | 说明 |
---|---|---|
————— | 0000 | 无权限 |
-rwx——— | 0700 | 只有所有者能够读取、写入和执行 |
-rwxrwx—- | 0770 | 所有者及其所在的用户组能够读取、写入和执行 |
-rwxrwxrwx | 0777 | 所有人能够读取、写入和执行 |
—-x—x—x | 0111 | 所有人都能够执行 |
—w—w—w- | 0222 | 所有人都能够写入 |
—wx-wx-wx | 0333 | 所有人都能够写入和执行 |
-r—r—r— | 0444 | 所有人都能够读取 |
-r-xr-xr-x | 0555 | 所有人都能都读取和执行 |
-rw-rw-rw- | 0666 | 所有人都能够读取和写入 |
-rwxr——- | 0740 | 所有者能够读取、写入和执行,而所有者所在的用户组能够读取 |
符号表示法是数字表示法的视觉表示:符号表示法总共包含10个字符。最左边的字符指出了文件是普通文件、目录还是其他东西,如果这个字符为-,就表示文件为普通文件,接下来的3个字符指定了文件所有者的权限;在接下来的3个字符表示所有者所在的用户组的权限,最后3个字符表示其他人的权限
在 UNIX 系统中,文件的默认权限为 0644 ,即所有者能够读取和写入。其他人只能够读取。
1 |
|
在当前的目录下创建了一个文件 test.txt
,并且文件权限为 0644
写入文件
使用 WriteFile
也可用来写入文件,如果指定的文件不存在,将会创建它
1 |
|
列出目录的内容
要处理文件系统中的文件,必须知道目录结构。为此,ioutil
包提供了便利函数 ReadDir, 它接收以字符串方式指定的目录名,并返回一个列表,其中包含按文件名排序的文件。文件名的类型为 FileInfo
,包含如下信息:
- Name: 文件的名称
- Size: 文件的长度,单位为字节
- Mode: 权限
- ModTime: 最后一次修改的时间
- IsDir: 文件是否为目录
- Sys: 底层数据源
1 |
|
执行上面将会看到下面的类似输出:
1 |
|
复制文件
ioutil
包可用于执行一些常见的文件操作,但要执行更复杂的操作,使用 os
包,os
包运行在稍低的层级,因此使用它时,必须手工关闭打开的文件。ioutil
包的很多函数都是os
包包装器
要复制文件,只需结合使用 os
包中的几个函数。以编程复制文件的步骤如下:
- 打开要复制的文件
- 读取其内容
- 创建并打开要将这些内容复制到其中的文件
- 将内容写入这个文件
- 关闭所有已打开的文件
1 |
|
删除文件
使用 os
包中的函数 Remove
即可删除文件,这个函数不会发出警告,也无法将删除的文件恢复,因此要务必谨慎
1 |
|
使用文件来管理配置
在编程中常使用文件来管理配置。考虑到代码可能在不同的环境中执行,可使用一个文件来设置各种用于启动程序的配置参数。使用文件是管理环境差异的有效方式,这种环境差别包括如下几个方面:
- Web 服务的 URL
- 访问密匙
- 端口号
- 环境变量
使用 JSON 文件
在声明可储存在文件中并在必要时读取的配置方面,JSON是一种卓有成效的标准方式。将配置储存在文件中的另一个优点是,可对其进行版本控制并集成到自动构建过程中。
通过将配置储存在 JSON 文件中,Go 程序中可读取这个文件,并将其作为配置数据使用
config.json:
1 |
|
1 |
|
使用 TOML 文件
TOML 是一种专为存储配置文件而设计的格式,它在 Go 社区中深受欢迎。相比于 JSON,其表达能力更强,且容易映射 Go 类型, JSON 是为序列化数据而设计的,而 TOML 是专门为储存配置文件而设计的,因此 TOML 相比于 JSON 有一定的优势,如更容易阅读、具备 JSON 没有的特性(如注释),在基本层面,TOML 的语法非常简单,可像 JSON 那样指定键和值
1 |
|
config.toml:
1 |
|
1 |
|
执行后将输出:1
{Name:dirname Blog:https://blog.forgiveher.cn Test:{Func:hello()}}
问题列表
ioutil
包为何没有提供用于执行复制文件等操作的函数Go 语言致力于确保核心库为小巧而轻量级的。另外,不同操作系统差别很大,这导致创建通用的问价你复制方法是很难的。
操作文件前,Go 会不会核实文件确实存在
不会,程序员必须在使用文件前核实它确实存在