创建文件和 ioutil 之间的争用条件.读取文件



我有一个允许上传图像的 golang Web 应用程序端点,但我发现创建一个文件并立即使用ioutil.ReadFile读取它会导致data为空。但是,如果我稍后再次调用它,它将包含数据。

r.ParseMultipartForm(32 << 20)
file, handler, err := r.FormFile("my_input_name")
f, err := os.OpenFile("./img_dump/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return
}
// data is empty [] when first called
data, err := ioutil.ReadFile("/myAbsolutePath/img_dump/"  + handler.Filename)
// This does not work, data is empty
fmt.Println(len(data))
f.Sync()
data, err = ioutil.ReadFile("/myAbsolutePath/img_dump/"  + handler.Filename)
// This does not work, data is empty
fmt.Println(len(data))
c1 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 5)
c1 <- "result 1"
}()
go func(name string) {
select {
case _ = <-c1:
data, err = ioutil.ReadFile("/myAbsolutePath/img_dump/" + name)
fmt.Println("after sleep")
// This only works if I don't try f.Close(), data is not empty
fmt.Println(len(data))
}
}(handler.Filename)

有没有办法避免创作和阅读之间的竞争条件,也许是一个承诺?

编辑:我尝试同步以刷新文件,但仍然存在相同的问题。

你试过使用 File.Sync 吗?

同步将文件的当前内容提交到稳定存储。 通常,这意味着刷新文件系统的内存中副本 最近将数据写入磁盘。

其他参考资料

f, err := os.OpenFile("./img_dump/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {...}
err = f.Sync()
if err != nil {...}
err = f.Close()
if err != nil {...}
data, err := ioutil.ReadFile("/myAbsolutePath/img_dump/"  + handler.Filename)

最新更新