文件操作-2-读操作
一 文件读取
文件读写的接口位于io包,file文件类是这些接口的实现类。
1.1 直接读取 read()
read() 实现的是按字节数读取:
readByte := make([]byte, 128) // 指定要读取的长度
for {
n, err := f.Read(readByte) // 将数据读取如切片,返回值 n 是实际读取到的字节数
if err != nil && err != io.EOF{ // 如果读到了文件末尾:EOF 即 end of file
fmt.Println("read file : ", err)
break
}
fmt.Println("read: ", string(readByte[:n]))
if n < 128 {
fmt.Println("read end")
break
}
}
1.2 bufio的写操作
bufio封装了io.Reader、io.Writer接口对象,并创建了另一个也实现了该接口的对象:bufio.Reader、bufio.Writer。通过该实现,bufio实现了文件的缓冲区设计,可以大大提高文件I/O的效率。
使用bufio读取文件时,先将数据读入内存的缓冲区(缓冲区一般比要比程序中设置的文件接收对象要大),这样就可以有效降低直接I/O的次数。
bufio.Read([]byte)
相当于读取大小len(p)
的内容:
- 当缓冲区有内容时,将缓冲区内容全部填入p并清空缓冲区
- 当缓冲区没有内容且
len(p)>len(buf)
,即要读取的内容比缓冲区还要大,直接去文件读取即可 - 当缓冲区没有内容且
len(p)<len(buf)
,即要读取的内容比缓冲区小,读取文件内容并填满缓冲区,并将p填满 - 以后再次读取时,缓冲区有内容,将缓冲区内容全部填入p并清空缓冲区(和第一步一致)
示例:
// 创建读对象
reader := bufio.NewReader(f)
// 读一行数据
byt, _ := reader.ReadBytes('\n')
fmt.Println(string(byt))
ReadString() 函数也具有同样的功能,且能直接读取到字符串数据,无需转换,示例:读取大文件的全部数据
reader := bufio.NewReader(f)
for { // 按照缓冲区读取:读取到特定字符结束
str, err := reader.ReadString('\n') // 按行读取
if err != nil && err != io.EOF {
fmt.Println("read err: ", err)
break
}
fmt.Println("str = ", str)
if err == io.EOF {
fmt.Print("read end")
break
}
}
在Unix设计思想中,一切皆文件,命令行输入也可以作为文件读入:
reader := bufio.NewReader(os.Stdin)
s, _ := reader.ReadString("-") // 假设命令行以 - 开始
缓冲的思想:通过bufio,数据被写入用户缓冲,再进入系统缓冲,最后由操作系统将系统缓冲区的数据写入磁盘。