
正如摘要所述,http.Request的FormFile方法仅能获取表单中的第一个文件。要处理包含multiple="multiple"属性的元素上传的多个文件,我们需要深入解析MultipartForm。
解析MultipartForm
FormFile函数是一个便捷方法,实际上,我们可以手动解析MultipartForm来获取我们需要的全部文件。以下是一个示例:
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
)
func uploadHandler(w http.ResponseWriter, r *http.Request) {
// 设置最大内存限制,例如32MB
err := r.ParseMultipartForm(32 << 20)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// 获取名为 "myfiles" 的文件列表
files := r.MultipartForm.File["myfiles"]
if len(files) == 0 {
fmt.Fprintln(w, "No files uploaded")
return
}
// 遍历文件列表
for _, fileHeader := range files {
// 打开文件
file, err := fileHeader.Open()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer file.Close()
// 创建保存文件的目标
dst, err := os.Create("./uploads/" + fileHeader.Filename)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer dst.Close()
// 将上传的文件内容复制到目标文件
if _, err := io.Copy(dst, file); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "Uploaded file: %s\n", fileHeader.Filename)
}
}
func main() {
// 创建 uploads 目录(如果不存在)
os.MkdirAll("./uploads", os.ModeDir|0755)
http.HandleFunc("/upload", uploadHandler)
fmt.Println("Server listening on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}代码解释:
- r.ParseMultipartForm(32 解析请求的MultipartForm,参数指定了最大内存限制,这里设置为32MB。 这与 FormFile 使用的默认值相同。 如果上传的文件大小超过此限制,将会返回错误。
- r.MultipartForm.File["myfiles"]: 从MultipartForm中获取名为"myfiles"的文件头信息切片。 "myfiles" 对应于 HTML 表单中 的 name 属性。
- fileHeader.Open(): 打开单个文件,返回一个io.ReadCloser接口,可以读取文件内容。
- os.Create("./uploads/" + fileHeader.Filename): 创建一个新的文件,用于保存上传的文件。 fileHeader.Filename 包含上传文件的原始文件名。
- io.Copy(dst, file): 将上传的文件内容从file复制到目标文件dst。
HTML表单示例:
立即学习“go语言免费学习笔记(深入)”;
File Upload
注意事项
- 错误处理: 代码中包含详细的错误处理,确保在文件上传过程中出现问题时能够及时捕获并处理。
- 文件大小限制: ParseMultipartForm函数的参数用于设置最大内存限制。 根据实际需求调整此值。 如果文件大小超过限制,将会返回错误。
- 文件存储: 示例代码将文件保存到 ./uploads/ 目录。 实际应用中,需要根据需求选择合适的文件存储方案,例如使用云存储服务(Amazon S3, Google Cloud Storage, Azure Blob Storage)。
- 安全: 上传的文件可能包含恶意代码。 在处理上传文件之前,务必进行安全检查,例如文件类型验证、病毒扫描等。
- 资源释放: 使用 defer 语句确保文件资源被正确释放,避免资源泄漏。
总结
通过解析MultipartForm,我们可以轻松地处理HTML表单中的多文件上传。 示例代码提供了一个清晰的框架,开发者可以根据自己的需求进行修改和扩展。 请务必注意错误处理、文件大小限制和安全问题,以确保文件上传功能的稳定性和安全性。










