2014-04-23 17 views
4

我用io.Copy()來複制文件,約700MB,但它導致了內存io.Copy事業中內存golang

bodyBuf := &bytes.Buffer{} 
bodyWriter := multipart.NewWriter(bodyBuf) 

//key step 
fileWriter, err := bodyWriter.CreateFormFile(paramName, fileName) 
if err != nil { 
    return nil, err 
} 

file, err := os.Open(fileName) //the file size is about 700Mb 
if err != nil { 
    return nil, err 
} 
defer file.Close() 

//iocopy 
copyLen, err := io.Copy(fileWriter, file) // this cause out of memory 
if err != nil { 
    fmt.Println("io.copy(): ", err) 

    return nil, err 
} 

錯誤信息如下:

runtime: memory allocated by OS (0x752cf000) not in usable range [0x18700000,0x98700000) 
runtime: out of memory: cannot allocate 1080229888-byte block (1081212928 in use) 
fatal error: out of memory 

我分配的BUF足夠的內存,它導致了內存在bodyWriter.CreateFormFile()

buf := make([]byte, 766509056) 
bodyBuf := bytes.NewBuffer(buf) 
bodyWriter := multipart.NewWriter(bodyBuf) 

fileWriter, err := bodyWriter.CreateFormFile(paramName, fileName) // out of memory 
if err != nil { 
    return nil, err 
} 
+0

請不要將鏈接發佈到圖像捕獲*文本在終端*當你可以複製和粘貼文本本身(就像你一樣) - 即使你得到足夠的聲譽;-) – kostix

回答

7

那是因爲你是「複製」,到bodyBuf,這是一個內存緩衝區,強制Go嘗試分配一個與整個文件一樣大的內存塊。

根據您對multipart的使用,看起來您正嘗試通過http流式傳輸文件?在這種情況下,請勿將bytes.Buffer傳遞給multipart.NewWriter,而是直接傳遞您的http連接。

+0

謝謝。你的意思是直接將文件寫入發佈請求主體? – clinyong

+0

取決於您是否將它作爲請求或響應發送,但基本上。 – Evan

+0

我仍然不能很好地工作。我設置了bodybuf足夠的內存,但同樣的問題(內存不足)發生在bodyWriter.CreateFormFile中。你能給我一個樣本嗎? – clinyong