无法覆盖文件内容

时间:2017-04-23 16:44:06

标签: file go overwrite

我在用零覆盖文件内容时遇到了麻烦。问题是原始文件的最后一个字节仍然存在,即使我超过其大小100个字节。有人知道我错过了什么?

func (h PostKey) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    f, err := os.Create("received.dat")
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    defer f.Close()

    _, err = io.Copy(f, r.Body)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    // Retrieve filesize
    size, _ := f.Seek(0, 1)
    zeroFilled := make([]byte, size + 100)
    n, err := f.WriteAt(zeroFilled, 0)
    if err != nil {
        return
    }

    fmt.Printf("Size: %d\n", size) // prints 13
    fmt.Printf("Bytes written: %d\n", n) // prints 113
}

2 个答案:

答案 0 :(得分:1)

问题可能是因为数据被写入http处理程序内的同一文件(共享资源),并且处理程序本身可能会同时执行。您需要在数据序列化(覆盖过程)期间锁定对文件的访问。快速解决方案将是:

import (
   "sync"
   //... other packages
)

var muFile sync.Mutex

func (h PostKey) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    muFile.Lock()
    defer muFile.Unlock()

    f, err := os.Create("received.dat")
    //other statements
    //...
}

如果您的服务器负载较低,上述解决方案就可以了。但是,如果您的服务器需要同时处理大量请求,则需要使用不同的方法(尽管规则相同,锁定对任何共享资源的访问权限)。

答案 1 :(得分:0)

I was writing to the file and trying to overwrite it in the same context, and so parts of the first write operation were still in memory and not yet written to the disk. By using f.Sync() to flush everything after copying the bodys content I was able to fix the issue.