持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
1.文件系统
对于文件和目录的操作,Go主要在os 提供了的相应函数:
func Mkdir(name string, perm FileMode) error
func Chdir(dir string) error
func TempDir() string
func Rename(oldpath, newpath string) error
func Chmod(name string, mode FileMode) error
func Open(name string) (*File, error) {
return OpenFile(name, O_RDONLY, 0)
}
func Create(name string) (*File, error) {
return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}
func OpenFile(name string, flag int, perm FileMode) (*File, error) {
testlog.Open(name)
return openFileNolog(name, flag, perm)
}
从上面函数定义我们可以发现:那就是os中不同函数打开(创建)文件的操作,最终还是通过OpenFile来实现,而OpenFile由编译器根据系统的情况来选择不同的底层功能来实现,可以根据标准包来仔细学习
os.Open(name string) 使用只读模式打开文件;
os.Create(name string) 创建新文件,如文件存在则原文件内容会丢失;
os.OpenFile(name string, flag int, perm FileMode) 这个函数可以指定flag和FileMode 。这三个函数都会返回一个文件对象。
在ioutil包中,也可以对文件操作,主要有下面三个函数:
这三个函数涉及到了文件IO ,而对文件的操作我们除了打开(创建),关闭外,更主要的是对内容的读写操作上,也即是文件IO处理上。在Go语言中,对于IO的操作在Go 语言很多标准库中存在,很难完整地讲清楚。下面我就尝试结合io, ioutil, bufio这三个标准库,讲一讲这几个标准库在文件IO操作中的具体使用方法。
2.IO读写
Go 语言中,为了方便开发者使用,将 IO 操作封装在了大概如下几个包中:
- io 为 IO 原语(I/O primitives)提供基本的接口
- io/ioutil 封装一些实用的 I/O 函数
- fmt 实现格式化 I/O,类似 C 语言中的 printf 和 scanf ,后面会详细讲解
- bufio 实现带缓冲I/O
在 io 包中最重要的是两个接口:Reader 和 Writer 接口。
这两个接口是我们了解整个IO的关键,我们只要记住:实现了这两个接口,就有了 IO 的功能。
有关缓冲:
- 内核中的缓冲:无论进程是否提供缓冲,内核都是提供缓冲的,系统对磁盘的读写都会提供一个缓冲(内核高速缓冲),将数据写入到块缓冲进行排队,当块缓冲达到一定的量时,才把数据写入磁盘。
- 进程中的缓冲:是指对输入输出流进行了改进,提供了一个流缓冲,当调用一个函数向磁盘写数据时,先把数据写入缓冲区,当达到某个条件,如流缓冲满了,或刷新流缓冲,这时候才会把数据一次送往内核提供的块缓冲中,再经块化重写入磁盘。
Go 语言提供了很多读写文件的方式,一般来说常用的有三种。 一:os.File 实现了Reader 和 Writer 接口,所以在文件对象上,我们可以直接读写文件。
func (f *File) Read(b []byte) (n int, err error)
func (f *File) Write(b []byte) (n int, err error)
在使用File.Read读文件时,可考虑使用buffer:
package main
import (
"fmt"
"os"
)
func main() {
b := make([]byte, 1024)
f, err := os.Open("./tt.txt")
_, err = f.Read(b)
f.Close()
if err != nil {
fmt.Println(err)
}
fmt.Println(string(b))
}