2017-02-15 1 views
1

POST 요청을 통해 서버로 파일을 보내려고합니다. 이 잘 작동하지만,이 POST 요청이 전송되기 전에 io.Copy 메모리에 전체 파일을 복사합니다 나의 이해파일을 메모리에로드하지 않고 http POST를 통해 os.Stdin을 보냅니다.

func newfileUploadRequest(uri string) (*http.Request, error) { 

    body := new(bytes.Buffer) 
    writer := multipart.NewWriter(body) 
    part, err := writer.CreateFormFile("file", "file") 
    if err != nil { 
     return nil, err 
    } 
    io.Copy(part, os.Stdin) 

    err = writer.Close() 
    if err != nil { 
     return nil, err 
    } 

    request, err := http.NewRequest("POST", uri, body) 
    if err != nil { 
     return nil, err 
    } 
    request.Header.Set("Content-Type", writer.FormDataContentType()) 
    return request, nil 
} 


func main() { 
    r, err := newfileUploadRequest("http://localhost:8080/") 
    if err != nil { 
     panic(err) 
    } 

    client := &http.Client{} 
    resp, err := client.Do(r) 
    if err != nil { 
     panic(err) 
    } 
    body, err := ioutil.ReadAll(resp.Body) 
    if err != nil { 
     panic(err) 
    } 
    print(string(body)) 
} 

입니다 :이 작업을 수행하려면 다음 코드를 사용합니다. 대용량 파일 (여러 GB)로 인해 문제가 발생합니다. 이것을 막을 수있는 방법이 있습니까? 내가 this을 찾았지만 단순히 io.Copy를 사용한다고합니다.

답변

2
당신은 io.Pipe과 goroutine를 사용하여 메모리에 데이터를 복사 피할 수

그 파일에서 파이프에 복사 :

func newfileUploadRequest(uri string) (*http.Request, error) { 
    r, w := io.Pipe() 
    writer := multipart.NewWriter(w) 
    go func() { 
    part, err := writer.CreateFormFile("file", "file") 
    if err != nil { 
     w.CloseWithError(err) 
     return 
    } 
    _, err = io.Copy(part, os.Stdin) 
    if err != nil { 
     w.CloseWithError(err) 
     return 
    } 
    err = writer.Close() 
    if err != nil { 
     w.CloseWithError(err) 
     return 
    } 
    }() 

    request, err := http.NewRequest("POST", uri, r) 
    if err != nil { 
    return nil, err 
    } 
    request.Header.Set("Content-Type", writer.FormDataContentType()) 
    return request, nil 
} 
1

사용 io.Pipe()-https://golang.org/pkg/io/#Pipe

당신은 goroutine를 사용해야합니다하지만 그렇게 너무 어렵지 않다. 구체적인 예가 필요한 경우 의견을 남겨두면 내가 가져올 수 있습니다.

관련 문제