我可以增加Golang的http流块大小吗?

时间:2017-06-01 22:59:59

标签: http go stream large-files

我正在尝试通过HTTP将数据(文件或其他)从客户端发送到服务器,并将其作为服务器中的流读取。

但是当我读取请求的正文时,我注意到了块大小或缓冲区大小,它固定为32kb。在尝试使用HTTP之前,我尝试使用TCP,缓冲区大小是预期的分配大小。

从请求收到的数据正在写入文件

问题:

  • 是否可以增加块/缓冲区大小?
  • 如果可能的话,通过使用更大的缓冲区大小会增加性能,因为对正在创建的文件的写入调用较少?
  • 如果不可能,我是否应该通过对正在创建的文件进行更多的写入调用来担心性能下降?
  • 使用TCP会更好吗?我真的需要标题和http响应

以下是一些插图代码:

client.go:

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"
)

func main() {
    addr := "http://localhost:8080"
    path := "path/to/file"

    sendHTTP(addr, path)
}

func sendHTTP(addr, path string) {
    f, err := os.Open(path)

    if err != nil {
        log.Fatal("Error opening file:", err)
    }

    client := &http.Client{}
    req, err := http.NewRequest("POST", addr, f)

    if err != nil {
        f.Close()
        log.Fatal("Error creating request:", err)
    }

    _, err = client.Do(req)

    if err != nil {
        f.Close()
        log.Fatal("Error doing request:", err)
    }
}

server.go:

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
)

func main() {
    addr := ":8080"

    http.HandleFunc("/", handler)

    http.ListenAndServe(addr, nil)
}

func handler(_ http.ResponseWriter, r *http.Request) {
    buf := make([]byte, 512*1024) // 512kb

    for {
        br, err := r.Body.Read(buf)

        if err == io.EOF {
            break
        } else if err != nil {
            log.Println("Error reading request:", err)
            break
        }

        fmt.Println(br) // is always 32kb
    }

}

1 个答案:

答案 0 :(得分:0)

调用 r.Body.Read(buf) 等待来自网络的数据并返回最多 len(buf) 字节的可用数据。调用时的可用数据量取决于客户端、服务器和网络上的时间和缓冲区大小。不容易控制。

<块引用>

从请求中接收到的数据正在写入文件

要以最有效的方式将数据写入文件,请使用 io.Copy 从请求正文复制到文件。下面是一个示例,其中 f 是您要写入的 *os.File

_, err := io.Copy(f, r.Body)
if err != nil {
     // handle error
}

在我撰写此答案时,io.Copy 函数调用 f.ReadFrom(r.Body) 将请求正文复制到文件中。