创建文件和ioutil.ReadFile之间的竞争条件

时间:2017-07-24 05:55:30

标签: go file-upload

我有一个允许上传图片的golang网络应用终端,但我发现创建一个文件并立即使用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)

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

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

1 个答案:

答案 0 :(得分:1)

您是否尝试过使用File.Sync

  

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

Additional Reference

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)