打开和关闭文件
os.open 打开一个文件,返回一个 *File
和一个 err
file, err := os.Open("./main.go")
file.Close() 关闭文件资源,为了防止文件忘记关闭,我们通常使用 defer 注册文件关闭语句
file, err := os.Open("./main.go")
file.Close()
文件读取
os.Open
会返回一个file指针,这个file指针有一个Read方法,可以把file里的内容读取到传入的切片参数里,并且返回读取的字节数和可能的具体错误,读到文件末尾时会返回 0
和 io.EOF
,一下例子,一次性读取指定大小的文件内容
func main() {
file, err := os.Open("./readme.txt")
defer file.Close()
if err != nil {
fmt.Println(err)
return
}
// 读取128个直接,如果文件大小小于128字节,则读取实际的大小
tmp := make([]byte, 128)
n, err := file.Read(tmp)
if err == io.EOF {
fmt.Println("文件读完了")
return
} else if err != nil {
fmt.Println(err)
return
}
fmt.Println("读取了", n, "字节的数据")
fmt.Println(string(tmp[:n])) // 字节切片转为字符串输出
}
可以使用for循环,读取文件的所有的内容
func main() {
file, err := os.Open("./readme.txt")
defer file.Close()
if err != nil {
fmt.Println(err)
return
}
var content []byte
// 一次读取128个字节,如果文件大小小于128字节,则读取实际的大小
tmp := make([]byte, 128)
for {
_, err := file.Read(tmp) // 每次读取,都会被重新赋值
if err == io.EOF {
fmt.Println("文件读完了")
break // 退出循环
} else if err != nil {
fmt.Println(err)
return // 错误的话直接结束
}
content = append(content, tmp...)
}
fmt.Println(string(content)) // 字节切片转为字符串输出
}
我们还还可以使用bufio包的NewReader方法,bufio 是在 file 的基础上封装了一层 API,支持更多的功能,按行来读取文件指针的内容
func main() {
file, err := os.Open("./readme.txt")
defer file.Close()
if err != nil {
fmt.Println(err)
return
}
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('\n') // 注意要用单引号
if err == io.EOF {
fmt.Println("文件读完了")
break // 退出循环
} else if err != nil {
fmt.Println(err)
return // 错误的话直接结束
}
fmt.Println(line)
}
}
读取整个文件的内容,还有一个更加简单的方法,就是io/ioutil 包的 ReadFile 方法能够读取完整的文件,只需要将文件名作为参数传入
func main() {
content, err := ioutil.ReadFile("./readme.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(content)) // 可以将byte切片转字符串
}
文件写入
os.OpenFile() 函数更加高级,可以指定是否可以往文件指针里写入内容
- os.O_WRONLY,只写
os.O_CREATE
,创建文件os.O_RDONLY
,只读os.O_RDWR
,读写os.O_TRUNC
,清空- os.O_APPEND,追加
func main() {
file, err := os.OpenFile("new.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
fmt.Println("打开文件错误:", err)
return
}
defer file.Close()
str := "hello world"
file.Write([]byte(str)) // 切片的形式写入
file.WriteString("你好,世界") // 字符串的形式写入
}
为了提高写入速度,可以用缓冲写入
func main() {
file, err := os.OpenFile("new.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
fmt.Println("打开文件错误:", err)
return
}
defer file.Close()
writer := bufio.NewWriter(file)
writer.WriteString("你好,世界!")
writer.Flush() // 要刷入磁盘
}
还可以使用ioutil.WriteFile 方式,直接写入
func main() {
str := "你好,世界!"
err := ioutil.WriteFile("./xx.txt", []byte(str), 0666)
if err != nil {
fmt.Println("err:", err)
}
}