问题描述
Golang在使用ioutil
写入文件,或是直接使用文件接口读写文件时,在写入后立刻断电,重启后文件存在,但是为空,没有任何数据,造成了数据丢失,代码如下:
package main
import (
"os"
)
func main() {
data := []byte("hello world!")
f, err := os.OpenFile("data.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
if err != nil {
panic(err)
}
defer f.Close()
_, err = f.Write(data)
}
原因及解决
操作系统为了系统性能考,写入文件并不会直接写入到磁盘,而是写入到缓存中,当满足一定条件时,一次性写入磁盘。
实际上操作系统也提供一些API可以将缓存写入磁盘,因此Golang对其进行了封装。
使用时只需要在打开文件时增加 os.O_SYNC
标识就可以
os.OpenFile("data.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
完整代码如下:
package main
import (
"os"
)
func main() {
data := []byte("hello world!")
f, err := os.OpenFile("data.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC|os.O_SYNC, os.ModePerm)
if err != nil {
panic(err)
}
defer f.Close()
_, err = f.Write(data)
}
参考文献
[1]. studygolang . Go语言标准库 - 6.1 文件 I/O . https://books.studygolang.com/The-Golang-Standard-Library-by-Example/chapter06/06.1.html
[2]. 知乎 . Linux下文件操作的缓冲机制探究 . SeeDeer . 2022.02 . https://zhuanlan.zhihu.com/p/473298019