## 介绍
---
```golang
// os.File
// 文件操作
// func Open(name string) (file *File, err error)
// Open打开一个文件用于读取。O_RDONLY模式。
// func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
// OpenFile是文件打开函数。指定打开模式。
const (
O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
O_RDWR int = syscall.O_RDWR // 读写模式打开文件
O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
O_CREATE int = syscall.O_CREAT // 如果不存在将创建一个新文件
O_EXCL int = syscall.O_EXCL // 和O_CREATE配合使用,文件必须不存在
O_SYNC int = syscall.O_SYNC // 打开文件用于同步I/O
O_TRUNC int = syscall.O_TRUNC // 如果可能,打开时清空文件
)
// func NewFile(fd uintptr, name string) *File
// NewFile使用给出的Unix文件描述符和名称创建一个文件。
// func Pipe() (r *File, w *File, err error)
// Pipe返回一对关联的文件对象。从r的读取将返回写入w的数据。
// io
// 属于底层接口定义库,其作用是是定义一些基本接口和一些基本常量。
// 常见的接口有Reader、Writer等。一般用这个库只是为了调用它的一些常量,比如io.EOF。
// bufio
// io库上再封装一层,加上了缓存功能。
// 读写缓存,减少io操作的次数。
// func NewReader(rd io.Reader) *Reader
// 使用默认缓冲区大小。defaultBufSize = 4096
// func NewReaderSize(rd io.Reader, size int) *Reader
// 使用自定义缓冲区大小
// func NewWriter(w io.Writer) *Writer
// 使用默认缓冲区大小。defaultBufSize = 4096
// func NewWriterSize(w io.Writer, size int) *Writer
// 使用自定义缓冲区大小
// func (b *Reader) Read(p []byte) (n int, err error)
// Read 从 b 中读出数据到 p 中,返回读出的字节数和遇到的错误。
// 如果缓存不为空,则只能读出缓存中的数据,不会从底层 io.Reader中提取数据。
// 如果缓存为空,则:
// 1、len(p) >= 缓存大小,则跳过缓存,直接从底层 io.Reader 中读出到 p 中。
// 2、len(p) < 缓存大小,则先将数据从底层 io.Reader 中读取到缓存中,再从缓存读取到 p 中。
// func (b *Reader) ReadString(delim byte) (string, error)
// func (b *Reader) ReadBytes(delim byte) ([]byte, error)
// func (b *Writer) Write(p []byte) (nn int, err error)
// 当写入内容小于缓冲区(buf)的可用大小时,内容写入缓存区(buf);
// 当缓冲区(buf)空间不够时,一次性将缓冲区(buf)内容写入文件,并清空缓存区(buf);
// 当写入内容大于缓冲区(buf)空间时,将内容直接写入文件;
// func (b *Writer) WriteByte(c byte) error
// func (b *Writer) WriteString(s string) (int, error)
// func (b *Writer) Flush() error
// ioutil
// 主要作用是作为一个工具包,里面有一些比较实用的函数。
// 唯一需要注意的是它们都是一次性读取和一次性写入,所以当读取的时候注意文件不能过大。
// func ReadAll(r io.Reader) ([]byte, error)
// func ReadFile(filename string) ([]byte, error)
// func WriteFile(filename string, data []byte, perm fs.FileMode) error
```
## 读取文件
---
- 全部读取
- 按字节数读取
- 按行读取
**1. 全部读取**
```golang
func readAll1() {
file, err := os.Open("a.txt")
if err != nil {
panic(err)
}
defer file.Close()
content, err := ioutil.ReadAll(file)
fmt.Println(string(content))
}
func readAll2() {
content ,err :=ioutil.ReadFile("a.txt")
if err !=nil {
panic(err)
}
fmt.Println(string(content))
}
```
**2. 按字节读取文件**
```golang
func readByte() {
file, err := os.Open("a.txt")
if err != nil {
panic(err)
}
defer file.Close()
// 使用默认缓存,defaultBufSize = 4096
reader := bufio.NewReader(file)
// 使用自定义缓存
reader := bufio.NewReaderSize(file, 1024*128)
chunks := make([]byte, 0)
buf := make([]byte, 1024)
for {
n, err := reader.Read(buf)
// 读取报错
if err != nil && err != io.EOF {
panic(err)
}
fmt.Println(string(buf[:n]))
// 读取完毕
if 0 == n || err == io.EOF {
break
}
chunks = append(chunks, buf[:n]...)
}
fmt.Println(string(chunks))
}
```
**3. 按行读取**
```golang
func readLine() {
file, err := os.Open("a.txt")
if err != nil {
fmt.Println("Open file error!", err)
return
}
defer file.Close()
// 使用默认缓存,defaultBufSize = 4096
reader := bufio.NewReader(file)
// 使用自定义缓存
reader := bufio.NewReaderSize(file, 1024*128)
for {
line, err := reader.ReadString('\n')
// 读取报错
if err != nil && err != io.EOF {
panic(err)
}
fmt.Println(line)
// 读取完毕
if err == io.EOF {
fmt.Println("read finished")
break
}
}
}
```
## 写入文件
---
**1. ioutil.WriteFile**
```golang
func writeByIoutil() {
content := []byte("测试1\n测试2\n")
err := ioutil.WriteFile("test.txt", content, 0644)
if err != nil {
panic(err)
}
}
```
这种方式每次都会覆盖 test.txt内容,如果test.txt文件不存在会创建。
**2. bufio**
```golang
func writeByBufio() {
file, err := os.OpenFile("a.txt",os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o644)
if err != nil {
fmt.Println("Open file error!", err)
return
}
defer file.Close()
writer := bufio.NewWriterSize(file, 1024*128)
content := []byte(time.Now().String() + "\n")
n, err := writer.Write(content)
if err != nil {
fmt.Println(err)
}
fmt.Printf("写入 %d 个字节n", n)
// 将缓存中的所有数据写入底层的 io.Writer 对象中
// 不主动刷新的话,缓存满了也会刷新到 io.Writer 对象中
writer.Flush()
}
```
## bufio 缓存
---
![image.png](https://blog.zs-fighting.cn/upload/2022/04/image-b66caf2fb7f0493381abb9956a7cef65.png)
Go 读写文件