-1

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.

user3591466
  • 797
  • 2
  • 8
  • 18

1 Answers1

1

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.

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)
John S Perayil
  • 6,001
  • 1
  • 32
  • 47