在Golang中访问上传的文件

huangapple go评论128阅读模式
英文:

Accessing Uploaded Files in Golang

问题

我在使用Golang上传文件时遇到了问题。我对这门语言非常陌生,尝试了很多次,但在网上找不到任何答案。

我做错了什么?在这段代码中,我从未进入列出已上传文件数量的代码块。

  1. func handler(w http.ResponseWriter, r *http.Request) {
  2. fmt.Println("handling req...")
  3. if r.Method == "GET" {
  4. fmt.Println("GET req...")
  5. } else {
  6. // 如果有的话,解析多部分内容
  7. err := r.ParseMultipartForm(15485760)
  8. if err == nil {
  9. form := r.MultipartForm
  10. if form == nil {
  11. fmt.Println("no files...")
  12. } else {
  13. defer form.RemoveAll()
  14. // 我从未看到这个实际发生
  15. fmt.Printf("%d files", len(form.File))
  16. }
  17. } else {
  18. http.Error(w, err.Error(), http.StatusInternalServerError)
  19. fmt.Println(err.Error())
  20. }
  21. }
  22. // fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
  23. fmt.Println("leaving...")
  24. }

更新

我已经成功让上述代码工作了,这太棒了。下面的答案展示了如何以异步方式完成,这可能是比我的代码示例更好的示例。

英文:

I'm having issues with accessing files i upload w/ golang. I'm really new to the language and have gone through more than a few attempts-- can't find any answers to this online either.

What am i doing wrong? In this code, i never get to the block where it lists the # of files uploaded.

  1. func handler(w http.ResponseWriter, r *http.Request) {
  2. fmt.Println("handling req...")
  3. if r.Method =="GET"{
  4. fmt.Println("GET req...")
  5. } else {
  6. //parse the multipart stuff if there
  7. err := r.ParseMultipartForm(15485760)
  8. //
  9. if err == nil{
  10. form:=r.MultipartForm
  11. if form==nil {
  12. fmt.Println("no files...")
  13. } else {
  14. defer form.RemoveAll()
  15. // i never see this actually occur
  16. fmt.Printf("%d files",len(form.File))
  17. }
  18. } else {
  19. http.Error(w,err.Error(),http.StatusInternalServerError)
  20. fmt.Println(err.Error())
  21. }
  22. }
  23. //fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
  24. fmt.Println("leaving...")
  25. }

###Update

I was able to get the above code to work. Which is great. The answer below shows how to do it async, which may be a better code sample than mine.

答案1

得分: 12

答案:下载最新的golang版本。

我之前遇到过这个问题,使用旧版本的golang时出现了问题,我不知道发生了什么,但是使用最新的golang版本就可以正常工作了。=)

以下是我的上传处理程序代码...
完整代码请参考:http://noypi-linux.blogspot.com/2014/07/golang-web-server-basic-operatons-using.html

  1. // 解析请求
  2. const _24K = (1 << 10) * 24
  3. if err = req.ParseMultipartForm(_24K); nil != err {
  4. status = http.StatusInternalServerError
  5. return
  6. }
  7. for _, fheaders := range req.MultipartForm.File {
  8. for _, hdr := range fheaders {
  9. // 打开上传的文件
  10. var infile multipart.File
  11. if infile, err = hdr.Open(); nil != err {
  12. status = http.StatusInternalServerError
  13. return
  14. }
  15. // 打开目标文件
  16. var outfile *os.File
  17. if outfile, err = os.Create("./uploaded/" + hdr.Filename); nil != err {
  18. status = http.StatusInternalServerError
  19. return
  20. }
  21. // 32K 缓冲区拷贝
  22. var written int64
  23. if written, err = io.Copy(outfile, infile); nil != err {
  24. status = http.StatusInternalServerError
  25. return
  26. }
  27. res.Write([]byte("uploaded file:" + hdr.Filename + ";length:" + strconv.Itoa(int(written))))
  28. }
  29. }
英文:

Answer Download the latest golang release.

I experienced the problem before, using the old golang versions, I do not know what happened, but with the latest golang its working. =)

My upload handler code below...
Full code at: http://noypi-linux.blogspot.com/2014/07/golang-web-server-basic-operatons-using.html

  1. // parse request
  2. const _24K = (1 &lt;&lt; 10) * 24
  3. if err = req.ParseMultipartForm(_24K); nil != err {
  4. status = http.StatusInternalServerError
  5. return
  6. }
  7. for _, fheaders := range req.MultipartForm.File {
  8. for _, hdr := range fheaders {
  9. // open uploaded
  10. var infile multipart.File
  11. if infile, err = hdr.Open(); nil != err {
  12. status = http.StatusInternalServerError
  13. return
  14. }
  15. // open destination
  16. var outfile *os.File
  17. if outfile, err = os.Create(&quot;./uploaded/&quot; + hdr.Filename); nil != err {
  18. status = http.StatusInternalServerError
  19. return
  20. }
  21. // 32K buffer copy
  22. var written int64
  23. if written, err = io.Copy(outfile, infile); nil != err {
  24. status = http.StatusInternalServerError
  25. return
  26. }
  27. res.Write([]byte(&quot;uploaded file:&quot; + hdr.Filename + &quot;;length:&quot; + strconv.Itoa(int(written))))
  28. }
  29. }

答案2

得分: 5

如果你知道文件上传的密钥,我认为可以简化一下(未经测试):

  1. infile, header, err := r.FormFile("file")
  2. if err != nil {
  3. http.Error(w, "解析上传文件时出错:"+err.Error(), http.StatusBadRequest)
  4. return
  5. }
  6. // 这样做非常不安全!请不要这样做!
  7. outfile, err := os.Create("./uploaded/" + header.Filename)
  8. if err != nil {
  9. http.Error(w, "保存文件时出错:"+err.Error(), http.StatusBadRequest)
  10. return
  11. }
  12. _, err = io.Copy(outfile, infile)
  13. if err != nil {
  14. http.Error(w, "保存文件时出错:"+err.Error(), http.StatusBadRequest)
  15. return
  16. }
  17. fmt.Fprintln(w, "Ok")
英文:

If you know they key of the file upload you can make it a bit simpler I think (this is not tested):

  1. infile, header, err := r.FormFile(&quot;file&quot;)
  2. if err != nil {
  3. http.Error(w, &quot;Error parsing uploaded file: &quot;+err.Error(), http.StatusBadRequest)
  4. return
  5. }
  6. // THIS IS VERY INSECURE! DO NOT DO THIS!
  7. outfile, err := os.Create(&quot;./uploaded/&quot; + header.Filename)
  8. if err != nil {
  9. http.Error(w, &quot;Error saving file: &quot;+err.Error(), http.StatusBadRequest)
  10. return
  11. }
  12. _, err = io.Copy(outfile, infile)
  13. if err != nil {
  14. http.Error(w, &quot;Error saving file: &quot;+err.Error(), http.StatusBadRequest)
  15. return
  16. }
  17. fmt.Fprintln(w, &quot;Ok&quot;)

huangapple
  • 本文由 发表于 2013年9月5日 23:08:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/18639929.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定