英文:
Race condition between creating file and ioutil.ReadFile
问题
我有一个使用golang编写的Web应用程序端点,允许上传图像,但我发现使用ioutil.ReadFile
创建文件并立即读取它会导致data
为空。但是,如果稍后再次调用它,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为空[]
data, err := ioutil.ReadFile("/myAbsolutePath/img_dump/" + handler.Filename)
// 这样不起作用,data为空
fmt.Println(len(data))
f.Sync()
data, err = ioutil.ReadFile("/myAbsolutePath/img_dump/" + handler.Filename)
// 这样不起作用,data为空
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")
// 只有在不尝试f.Close()时才起作用,data不为空
fmt.Println(len(data))
}
}(handler.Filename)
有没有办法避免创建和读取之间的竞争条件,也许使用promise?
编辑:我尝试使用Sync刷新文件,但问题仍然存在。
英文:
I have a golang web app end point that allows uploading image, but I find that creating a file and immediately reading it using ioutil.ReadFile
will result in data
to be empty. But if I call it again in some time later it will contain the 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)
Is there a way to avoid race condition between creating and reading, maybe a promise?
Edit: I tried Sync to flush file but same issue still exist.
答案1
得分: 1
你尝试过使用File.Sync吗?
> 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)
英文:
Have you tried using File.Sync ?
> Sync commits the current contents of the file to stable storage.
> Typically, this means flushing the file system's in-memory copy of
> recently written data to disk.
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论