1. 文件的重要性
文件的本质就是硬盘中的数据,包括各种程序、文档、多媒体甚至系统配置。
各种类UNIX操作系统的一个重要特征就是将一切皆视为文件。
- 可以象访问文件一样访问键盘、打印机等硬件设备
- 可以象访问文件一样访问管道、套接字等内核资源
各种类UNIX操作系统甚至可以通过虚拟文件来暴露系统信息。
- 执行cat /proc/loadavg命令,可以查看系统的当前负载信息
- 1.75 0.87 0.34 1/701 2348
- 执行watch cat /proc/loadavg命令,可以2秒为周期,动态显式系统负载的实时视图。
- Every 2.0s: cat /proc/loadavg
1.32 0.33 0.11 1/869 3245
- Every 2.0s: cat /proc/loadavg
- 事实上,loadavg并不是真正的磁盘文件,其本质是虚拟文件形式表现的内核信息。
2. ioutil包(读取/创建文件)
Go语言标准库通过os包实现对文件系统的基本访问,并在此基础上做了更高级的封装,以io/ioutil包的形式简化读写文件的过程,其中包括自动化清理。
- 通过ioutil包读取文件、创建文件、写入文件、创建临时文件、创建临时目录、列出目录内容,等等
(一)读取文件
io/ioutil包的ReadFile函数接受文件路径作为参数,读取文件的内容,并以字节切片的形式返回。要将文件内容作为字符串处理,可对其显式类型转换
- fileBytes, err := ioutil.ReadFile("./main.go")
- fileString := string(fileBytes) // 如果文件本身是文本文件的话,可以显示转化为字符串,进而获取其中内容。
注意只有文本文件的内容才能被当作字符串处理。很多文件,比如:可执行程序文件、图像文件、音视频文件等,都属于二进制文件。一些经过压缩和加密处理的文本文件也是二进制文件。这些文件的内容都不能转换为字符串。
// 读取文件
// ioutil包的ReadFile函数接受一个文件路径
// 作为参数,并以字节切片的形式返回文件内容
// 字节切片 = ioutil.ReadFile(文件路径)
package main
import ("fmt""io/ioutil""log"
)
func main() {// 读取main.go文件fileBytes, err := ioutil.ReadFile("./main.go")if err != nil {log.Fatal(err)}fileString := string(fileBytes)fmt.Println(fileString)
}
// 打印输出:
// ioutil包的ReadFile函数接受一个文件路径作为参数,并以字节切片的形式返回文
// 件内容字节切片 = ioutil.ReadFile(文件路径)package mainimport ("fmt""io/ioutil""log")func main() {fileBytes, err := ioutil.ReadFile("./main.go")if err != nil {log.Fatal(err)}fileString := string(fileBytes)fmt.Println(fileString)}
(二)创建文件
io/ioutil包的WriteFile函数可用于创建新文件。该函数接受文件路径、写入数据及文件权限三个参数。如果文件路径所表示的文件并不存在,但其所属目录存在且写入数据为nil,该函数将按照给定的路径和权限创建一个空文件。
- err := ioutil.WriteFile("./file.txt", nil, 0644)
文件权限用三位八进制数表示:0UGO
- U、G、O分别表示拥有者用户的权限、拥有组用户的权限、其它用户的权限。
- 每种权限用4、2、1三个数中的部分或全部相加求和得到。
- 4、2、1这三个数分别表示可读、可写、可执行。
- 例如:某文件的权限是0764,其字符串形式是rwxrw-r--
- 拥有者用户可读可写可执行:7=4+2+1
- 拥有组用户可读写不可执行:6=4+2
- 其它用户只读不可写和执行:4=4
// 创建文件
// ioutil包WriteFile函数的本意是将数据写入文件,
// 但在被写入文件并不存在的情况下也会先创建文件
// ioutil.WriteFile(文件路径, 被写入数据, 文件权限)
//
// 其中文件权限用三位八进制数表示:0UGO
// U - 拥有者用户的权限
// G - 拥有组用户的权限
// O - 其它用户的权限
//
// 其中每一种权限用4、2、1三个数中的部分或全
// 部相加求和得到,分别表示可读、可写、可执行
//
// 0 7 6 4 -rwxrw-r--
// | | |
// | | +------- 4 - 其它用户只读
// | +----- 4+2 - 拥有组用户可读可写
// +--- 4+2+1 - 拥有者用户可读可写可执行
package mainimport ("io/ioutil""log"
)func main() {err := ioutil.WriteFile("./file.txt", nil, 0644)if err != nil {log.Fatal(err)}
}
3. 写入文件
io/ioutil包的WriteFile函数也可用于写入文件。需要写入的内容可通过该函数的第二个参数以字节切片的形式传入。
- err := ioutil.WriteFile("./file.txt", fileBytes, 0644)
如果需要写入文件的内容是字符串,则需要先将其转换为字节切片。
- fileString := "Hello World!"
fileBytes := []byte(fileString) // 转换为字节切片
注意,通过io/ioutil包的WriteFile函数向文件写入数据:
- 如果被写入文件已存在,则先清空原有内容再写入新内容,文件权限参数不起作用。
如果被写入文件不存在,则按照给定的文件权限创建一个新文件,然后再写入数据。
// 写入文件
// ioutil包WriteFile函数的本意是将数据写入文件,
// 但在被写入文件并不存在的情况下也会先创建文件
// ioutil.WriteFile(文件路径, 被写入数据, 文件权限)
// 其中被写入数据采用字节切片的形式传入
package main
import ("io/ioutil""log"
)
func main() {fileString := "Hello World!"fileBytes := []byte(fileString)err := ioutil.WriteFile("./file.txt", fileBytes, 0644)if err != nil {log.Fatal(err)}fileBytes, err := ioutil.ReadFile("./file.txt")if err != nil {log.Fatal(err)}fileString := string(fileBytes)fmt.Println(fileString)
}
// 打印输出:
Hello World!