When I io.Copy a file, it doesn't block and trying to use it might fail until it finishes

Viewed 164

I have this code (more or less):

resp, err := http.Get(url)
if err != nil {
    // handle error
}

if resp.StatusCode != http.StatusOK {
    // handle error
}

out, err := os.Create(filepath)
if err != nil {
    return err
}

// Write the body to file
_, err = io.Copy(out, resp.Body)
resp.Body.Close()
out.Close()

My issue is that if I immediately try to do something (e.g. take the hash of this file), then I see that it is still copying for a while.

At first I was deferring the out.Close(), and I though that I need to out.Close after the io.Copy, which will block until its done with it. or so I thought. This didn't work and I still have the same issue.

How do I block or wait for the io.Copy operation to finish?

Thanks!

1 Answers

Likely you are hitting some disk buffer/cache, where your OS or disk device keeps some data in memory before actually persisting the write to the disk.

Calling

out.Sync()

forces a fsync syscall, which will instruct the OS to force a flush of the buffer and write the data to disk. I suggest calling out.Flush() after the io.Copy call returns.

Related docs you may find interesting:

Related