有很多关于使用http.Request
go 发布文件的教程,但是几乎总是以这样的方式开始:
file, err := os.Open(path)
if err != nil {
return nil, err
}
fileContents, err := ioutil.ReadAll(file)
也就是说,您将整个文件读入内存,然后将其转换为Buffer
并将其传递给请求,如下所示:
func send(client *http.Client, file *os.File, endpoint string) {
body := &bytes.Buffer{}
io.Copy(body, file)
req, _ := http.NewRequest("POST", endpoint, body)
resp, _ := client.Do(req)
}
如果您想发布海量文件并避免将其读取到内存中,而是将文件分块蒸出……您将如何做?
如果需要设置Content-Length
,可以手动完成。以下代码段是将文件和其他参数作为流上传的示例(基于Golang中无缓冲区Multipart
POST的代码
)
//NOTE: for simplicity, error check is omitted
func uploadLargeFile(uri, filePath string, chunkSize int, params map[string]string) {
//open file and retrieve info
file, _ := os.Open(filePath)
fi, _ := file.Stat()
defer file.Close()
//buffer for storing multipart data
byteBuf := &bytes.Buffer{}
//part: parameters
mpWriter := multipart.NewWriter(byteBuf)
for key, value := range params {
_ = mpWriter.WriteField(key, value)
}
//part: file
mpWriter.CreateFormFile("file", fi.Name())
contentType := mpWriter.FormDataContentType()
nmulti := byteBuf.Len()
multi := make([]byte, nmulti)
_, _ = byteBuf.Read(multi)
//part: latest boundary
//when multipart closed, latest boundary is added
mpWriter.Close()
nboundary := byteBuf.Len()
lastBoundary := make([]byte, nboundary)
_, _ = byteBuf.Read(lastBoundary)
//calculate content length
totalSize := int64(nmulti) + fi.Size() + int64(nboundary)
log.Printf("Content length = %v byte(s)\n", totalSize)
//use pipe to pass request
rd, wr := io.Pipe()
defer rd.Close()
go func() {
defer wr.Close()
//write multipart
_, _ = wr.Write(multi)
//write file
buf := make([]byte, chunkSize)
for {
n, err := file.Read(buf)
if err != nil {
break
}
_, _ = wr.Write(buf[:n])
}
//write boundary
_, _ = wr.Write(lastBoundary)
}()
//construct request with rd
req, _ := http.NewRequest("POST", uri, rd)
req.Header.Set("Content-Type", contentType)
req.ContentLength = totalSize
//process request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
} else {
log.Println(resp.StatusCode)
log.Println(resp.Header)
body := &bytes.Buffer{}
_, _ = body.ReadFrom(resp.Body)
resp.Body.Close()
log.Println(body)
}
}
问题内容: 作为Django的新手,我很难在Django 1.3中制作上传应用程序。我找不到任何最新的示例/代码段。有人可以发布最少但完整的(模型,视图,模板)示例代码来这样做吗? 问题答案: ew,Django文档确实没有很好的例子。我花了2个多小时来挖掘所有内容,以了解其工作原理。有了这些知识,我实现了一个项目,该项目可以上传文件并将其显示为列表。要下载该项目的源代码,请访问https://g
我正在尝试使用多部分实体方法上传文件。但它失败,错误说{“错误”:“文件参数值'无'无效”} 我的代码是: File File = new File(" C:/Users/SST-06/Desktop/new . txt "); 我的实体文件包含所有提到的参数。 -hkYO-pblk 0 uqlxjtvklrbkosxz 7 mye-8 wbvbvanx Content-Disposition:f
问题内容: 我正在尝试使用以下代码:- 我没有得到结果。 问题答案: 您可以使用AutoIT或JAVA代码。下面我将两者都用作您的参考。尝试任何一个 AutoIt中的代码是 希望这给你一个主意
问题内容: 我知道有些东西像和一样强大。我想知道有没有机会上传没有文件的文件。 问题答案: 如果要上传文件,则需要能够解析多部分内容。您可以使用它来解析或实现自己的解析。以下列出了可以帮助您的模块: 直接解析(基于截至2016年11月的Github星,以递减的形式出现): 强大 男生 多党 中间件: multer-基于busboy,比下面的选项更受欢迎 busboy中间件 -上一次提交2014年4
2FE552B7-53B1-4E4A-AFFF-3AEF8FE9D05B-----WebKitFormBoundaryLH8FJWGYEEVTCJMA内容-配置:表单-数据;name=“sample test file.pdf”;filename=“sample test file.pdf”content-type:application/pdf
问题内容: 我正在编写一个Play 2.0 Java应用程序,该应用程序允许用户上传文件。这些文件存储在我使用Java库访问的第三方服务上,我在此API中使用的方法具有以下签名: 我设法使用以下简单控制器使上传正常工作: 我担心的是该解决方案效率不高,因为默认情况下,播放框架会将客户端上传的所有数据存储在服务器上的临时文件中,然后在控制器中调用我的uploadFile()方法。 在传统的servl