Go 文件操作-读写文件
Go读取文件
整个文件读取进内存(适合读小文件)
1. 直接指定文件名读取
os.ReadFile()
ioutil.ReadFile() (在 Go 1.16 开始,ioutil.ReadFile() 就等价于 os.ReadFile())
package main
import (
"fmt"
"os"
)
func main() {
bytes, err := os.ReadFile("./Readme.md")
if err != nil {
fmt.Println("os.ReadFile err=", err)
}
fmt.Println(string(bytes))
}
2. 先创建文件句柄再读取
可以使用 os.Open() 或者 os.OpenFile() 创建文件句柄
io.ReadAll() (在 Go 1.16 开始,ioutil.ReadAll() 就等价于 io.ReadAll())
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("./Readme.md")
if err != nil {
fmt.Println("os.Open err=", err)
}
defer file.Close()
bytes, err := io.ReadAll(file)
if err != nil {
fmt.Println("io.ReadAll err=", err)
}
fmt.Println(string(bytes))
}
使用缓冲,每次只读一行(适合读大文件,不通用)
使用 bufio.NewReader() 构建 Reader 实例
func (*bufio.Reader) ReadLine()
(在 bufio 的源码注释中,曾说道 bufio.ReadLine() 是低级库,不太适合普通用户使用,
更推荐用户使用 bufio.ReadBytes 和 bufio.ReadString 去读取单行数据。)
func (*bufio.Reader) ReadBytes('\n')(并不是所有的文件都有换行符 \n)
func (*bufio.Reader) ReadString('\n')(并不是所有的文件都有换行符 \n)
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("./Readme.md")
if err != nil {
fmt.Println("os.Open err=", err)
}
defer file.Close()
r := bufio.NewReader(file)
for true {
lineBytes, err := r.ReadBytes('\n')
//line := strings.TrimSpace(string(lineBytes))
// 特别注意!
// 如果ReadBytes在查找分隔符之前遇到错误,
// 它会返回错误之前读取的数据和错误本身(通常为io.EOF)
// 所以需要注意错误的判断条件 和 读取文件操作代码的位置
if err != nil && err != io.EOF {
fmt.Println("r.ReadBytes err=", err)
}
// 应在 break 之前
fmt.Printf(string(lineBytes))
if err == io.EOF {
break
}
}
}
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("./Readme.md")
if err != nil {
fmt.Println("os.Open err=", err)
}
defer file.Close()
r := bufio.NewReader(file)
for true {
lineStr, err := r.ReadString('\n')
//line := strings.TrimSpace(string(lineBytes))
// 特别注意!
// 如果ReadBytes在查找分隔符之前遇到错误,
// 它会返回错误之前读取的数据和错误本身(通常为io.EOF)
// 所以需要注意错误的判断条件 和 读取文件操作代码的位置
// 可以先读取文件 打印 方便后面的错误处理
fmt.Printf(lineStr)
if err == io.EOF {
break
}
if err != nil {
fmt.Println("r.ReadString err=", err)
}
}
}
使用缓冲,每次只读固定字节数(适合读大文件,通用)
- 先创建一个文件句柄,可以使用 os.Open() 或者 os.OpenFile()
- 然后 bufio.NewReader() 创建一个 Reader
- 然后在 for 循环里调用 Reader 的 Read() 函数,每次仅读取固定字节数量的数据。
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("./Readme.md")
if err != nil {
fmt.Println("os.Open err=", err)
}
defer file.Close()
r := bufio.NewReader(file)
buf := make([]byte, 1024)
for true {
//Read读取数据写入buf。
//本方法返回写入buf的字节数。
//本方法一次调用最多会调用下层Reader接口一次Read方法,
//因此返回值n可能小于len(p)。
//读取到达结尾时,返回值n将为0而err将为io.EOF。
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
// 注意转换string时 buf字节要取出确定的长度
fmt.Println(string(buf[:n]))
}
}
Go写文件
一次将全部内容写入文件
1. 指定文件名,不存在则创建文件后写入,存在则清空文件后写入
os.WriteFile()
ioutil.WriteFile() (在 Go 1.16 开始,ioutil.WriteFile() 就等价于 os.WriteFile())
package main
import (
"fmt"
"os"
)
func main() {
err := os.WriteFile("abc.text", []byte("hello,world"), 0666)
if err != nil {
fmt.Println("os.WriteFile err=", err)
}
}
2. 先创建文件句柄再写入
可以使用 os.Create() 或者 os.OpenFile() 创建文件句柄
func (*File) Write()
func (*File) WriteAt()
func (*File) WriteString()
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Create("abc.text")
if err != nil {
fmt.Println("os.Create err=", err)
}
defer file.Close()
n, err := file.Write([]byte("How are you"))
if err != nil {
fmt.Println("file.Write err=", err)
}
fmt.Println(n)
}
使用缓冲
可以使用 os.Create() 或者 os.OpenFile() 创建文件句柄
使用 bufio.NewWriter() 构建 Writer 实例
func (*bufio.Writer) WriteString() + func (*bufio.Writer) Flush()
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, err := os.Create("abc.text")
if err != nil {
fmt.Println("os.Create err=", err)
}
defer file.Close()
w := bufio.NewWriter(file)
for i := 0; i < 10; i++ {
n, err := w.WriteString("I am fine\n")
if err != nil {
fmt.Println("file.Write err=", err)
}
fmt.Println(n) //
}
err = w.Flush()
if err != nil {
fmt.Println("w.Flush err=", err)
}
}
方法总结
读 | 写 | |
---|---|---|
一次性读写,且不使用文件句柄 | os.ReadFile() | os.WriteFile() |
一次性读写,使用文件句柄 | os.Open() + io.ReadAll() | os.Create() + func (*File) WriteString() |
使用缓冲 | os.Open() + bufio.NewReader() + func (*bufio.Reader) Read() | os.Create() + bufio.NewWriter() + func (*bufio.Writer) WriteString() + func (*bufio.Writer) Flush() |