无法覆盖文件内容
Trouble overwriting file content
我无法用零覆盖文件内容。问题是原始文件的最后一个字节仍然存在,即使我超过了它的大小 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
}
发生此问题的原因可能是数据写入了 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
//...
}
如果您的服务器负载较低,上述解决方案就可以了。但是如果你的服务器需要并发处理很多请求,你需要使用不同的方法(虽然规则是一样的,锁定对任何共享资源的访问)。
我正在写入文件并试图在相同的上下文中覆盖它,因此第一次写入操作的部分内容仍在内存中,尚未写入磁盘。通过在复制正文内容后使用 f.Sync()
刷新所有内容,我能够解决问题。
我无法用零覆盖文件内容。问题是原始文件的最后一个字节仍然存在,即使我超过了它的大小 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
}
发生此问题的原因可能是数据写入了 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
//...
}
如果您的服务器负载较低,上述解决方案就可以了。但是如果你的服务器需要并发处理很多请求,你需要使用不同的方法(虽然规则是一样的,锁定对任何共享资源的访问)。
我正在写入文件并试图在相同的上下文中覆盖它,因此第一次写入操作的部分内容仍在内存中,尚未写入磁盘。通过在复制正文内容后使用 f.Sync()
刷新所有内容,我能够解决问题。