2017-04-23 119 views
-1

我很難用零覆蓋文件內容。問題是原始文件的最後一個字節仍然存在,即使我超過了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

你能分享身體的內容嗎?最後一個沒有被覆蓋的字節是什麼?使用你的代碼,我似乎無法重現你的問題。 [這裏是遊樂場](https://play.golang.org/p/0mASED0hSs) – mkopriva

+0

你還沒有提供代碼來重現問題。尋求調試幫助的問題(「爲什麼這個代碼不工作?」)必須包含所需的行爲,特定的問題或錯誤以及在問題本身中重現問題所需的最短代碼。 – peterSO

回答

0

我正在寫入該文件並試圖在相同的上下文中覆蓋它,因此第一次寫入操作的部分內容仍在內存中,尚未寫入磁盤。通過使用f.Sync()在複製bodys內容後刷新所有內容,我可以解決問題。

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

如果您的服務器負載較低,上述解決方案將罰款。但是,如果您的服務器需要同時處理大量請求,則需要使用不同的方法(雖然規則相同,但可以鎖定對任何共享資源的訪問)。