无法覆盖文件内容

无法覆盖文件内容

问题描述:

I've got trouble overwriting a files content with zeros. The problem is that the very last byte of the original file remains, even when I exceed its size by 100 bytes. Someone got an idea what I'm missing?

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
", size) // prints 13
    fmt.Printf("Bytes written: %d
", n) // prints 113
}

我很难用零覆盖文件内容。 问题是,即使我超出其大小100个字节,原始文件的最后一个字节仍然保留。 有人知道我缺少什么? p>

  func(h PostKey)ServeHTTP(w http.ResponseWriter,r * http.Request){
f,err:= os  .Create(“ received.dat”)
 if err!= nil {
 w.WriteHeader(http.StatusInternalServerError)
 return 
} 
推迟f.Close()
 
 _,err = io  .Copy(f,r.Body)
如果err!= nil {
 w.WriteHeader(http.StatusInternalServerError)
 return 
} 
 
 //检索文件大小
大小,_:= f。 搜寻(0,1)
 zeroFilled:= make([] byte,size + 100)
n,err:= f.WriteAt(zeroFilled,0)
 if err!= nil {
 return 
} \  n 
 fmt.Printf(“ Size:%d 
”,size)//打印13 
 fmt.Printf(“写入的字节:%d 
”,n)//打印113 
} 
   pre> 
  div>

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.

The problem may occurred because the data is written into a same file (shared resource) inside an http handler, and the handler itself may be executed concurrently. You need to lock access to the file during data serialization (overwriting process). Quick solution will be:

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
    //...
}

If your server load is low, the above solution will be fine. But if your server needs to handle a lot of requests concurrently, you need to use different approach (although the rule is the same, lock access to any shared resource).