Golang HTTP文件上传
2018年02月08日 10:07:13 冷月醉雪 阅读数:346
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lengyuezuixue/article/details/79277691
首先,我们在服务器端设定两个路由,/upload用于文件上传,/files/*用于文件下载。
-
const maxUploadSize = 2 * 1024 * 2014 // 2 MB
-
const uploadPath = "./tmp"
-
-
func main() {
-
http.HandleFunc("/upload", uploadFileHandler())
-
-
fs := http.FileServer(http.Dir(uploadPath))
-
http.Handle("/files/", http.StripPrefix("/files", fs))
-
-
log.Print("Server started on localhost:8080, use /upload for uploading files and /files/{fileName} for downloading files.")
-
log.Fatal(http.ListenAndServe(":8080", nil))
-
}
现在我们只需要实现uploadFileHander.这个处理程序将包含以下功能:
·验证文件最大值;
·从请求验证文件和POST参数
·检查所提供的文件类型
·创建一个随机文件名
·将文件写入硬盘
·处理所有错误,如果一切顺利返回成功消息
第一步,我们定义处理程序:
-
func uploadFileHandler() http.HandlerFunc {
-
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-
r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
-
if err := r.ParseMultipartForm(maxUploadSize); err != nil {
-
renderError(w, "FILE_TOO_BIG", http.StatusBadRequest)
-
return
-
}
-
fileType := r.PostFormValue("type")
-
file, _, err := r.FormFile("uploadFile")
-
if err != nil {
-
renderError(w, "INVALID_FILE", http.StatusBadRequest)
-
return
-
}
-
defer file.Close()
-
fileBytes, err := ioutil.ReadAll(file)
-
if err != nil {
-
renderError(w, "INVALID_FILE", http.StatusBadRequest)
-
return
-
}
幸运的是,Go标准库提供给我们一个Http.DetectConntectType函数,这个函数基于mimesniff算法,祝需要读取文件的512个字节就能够判断文件的类型。
-
iletype := http.DetectContentType(fileBytes)
-
if filetype != "image/jpeg" && filetype != "image/jpg" &&
-
filetype != "image/gif" && filetype != "image/png" &&
-
filetype != "application/pdf" {
-
renderError(w, "INVALID_FILE_TYPE", http.StatusBadRequest)
-
return
-
}
-
fileName := randToken(12)
-
fileEndings, err := mime.ExtensionsByType(fileType)
-
if err != nil {
-
renderError(w, "CANT_READ_FILE_TYPE", http.StatusInternalServerError)
-
return
-
}
-
newPath := filepath.Join(uploadPath, fileName+fileEndings[0])
-
fmt.Printf("FileType: %s, File: %s\n", fileType, newPath)
如果所有部分都没问题,我们给用户返回一个i额SUCCESS信息。
-
newFile, err := os.Create(newPath)
-
if err != nil {
-
renderError(w, "CANT_WRITE_FILE", http.StatusInternalServerError)
-
return
-
}
-
defer newFile.Close()
-
if _, err := newFile.Write(fileBytes); err != nil {
-
renderError(w, "CANT_WRITE_FILE", http.StatusInternalServerError)
-
return
-
}
-
w.Write([]byte("SUCCESS"))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人