在Golang中访问上传的文件

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

Accessing Uploaded Files in Golang

问题

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

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

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Println("handling req...")

  if r.Method == "GET" {
    fmt.Println("GET req...")
  } else {
    // 如果有的话,解析多部分内容
    err := r.ParseMultipartForm(15485760)

    if err == nil {
      form := r.MultipartForm
      if form == nil {
        fmt.Println("no files...")
      } else {
        defer form.RemoveAll()
        // 我从未看到这个实际发生
        fmt.Printf("%d files", len(form.File))
      }
    } else {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      fmt.Println(err.Error())
    }
  }

  // fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
  fmt.Println("leaving...")
}

更新

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

英文:

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.

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Println("handling req...")

  if r.Method =="GET"{
	fmt.Println("GET req...")

  } else {

	//parse the multipart stuff if there
	err := r.ParseMultipartForm(15485760)

	//
	if err == nil{
		form:=r.MultipartForm
		if form==nil {
			fmt.Println("no files...")

		} else {
			defer form.RemoveAll()
			// i never see this actually occur
			fmt.Printf("%d files",len(form.File))
		}
	} else {
		http.Error(w,err.Error(),http.StatusInternalServerError)
		fmt.Println(err.Error())
	}
  }

  //fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
  fmt.Println("leaving...")
}

###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

// 解析请求
const _24K = (1 << 10) * 24
if err = req.ParseMultipartForm(_24K); nil != err {
     status = http.StatusInternalServerError
     return
}
for _, fheaders := range req.MultipartForm.File {
     for _, hdr := range fheaders {
          // 打开上传的文件
          var infile multipart.File
          if infile, err = hdr.Open(); nil != err {
               status = http.StatusInternalServerError
               return
          }
          // 打开目标文件
          var outfile *os.File
          if outfile, err = os.Create("./uploaded/" + hdr.Filename); nil != err {
               status = http.StatusInternalServerError
               return
          }
          // 32K 缓冲区拷贝
          var written int64
          if written, err = io.Copy(outfile, infile); nil != err {
               status = http.StatusInternalServerError
               return
          }
          res.Write([]byte("uploaded file:" + hdr.Filename + ";length:" + strconv.Itoa(int(written))))
     }
}
英文:

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

  // parse request  
  const _24K = (1 &lt;&lt; 10) * 24  
  if err = req.ParseMultipartForm(_24K); nil != err {  
       status = http.StatusInternalServerError  
       return  
  }  
  for _, fheaders := range req.MultipartForm.File {  
       for _, hdr := range fheaders {  
            // open uploaded  
            var infile multipart.File  
            if infile, err = hdr.Open(); nil != err {  
                 status = http.StatusInternalServerError  
                 return  
            }  
            // open destination  
            var outfile *os.File  
            if outfile, err = os.Create(&quot;./uploaded/&quot; + hdr.Filename); nil != err {  
                 status = http.StatusInternalServerError  
                 return  
            }  
            // 32K buffer copy  
            var written int64  
            if written, err = io.Copy(outfile, infile); nil != err {  
                 status = http.StatusInternalServerError  
                 return  
            }  
            res.Write([]byte(&quot;uploaded file:&quot; + hdr.Filename + &quot;;length:&quot; + strconv.Itoa(int(written))))  
       }  
  }  

答案2

得分: 5

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

infile, header, err := r.FormFile("file")
if err != nil {
	http.Error(w, "解析上传文件时出错:"+err.Error(), http.StatusBadRequest)
	return
}

// 这样做非常不安全!请不要这样做!
outfile, err := os.Create("./uploaded/" + header.Filename)
if err != nil {
	http.Error(w, "保存文件时出错:"+err.Error(), http.StatusBadRequest)
	return
}

_, err = io.Copy(outfile, infile)
if err != nil {
	http.Error(w, "保存文件时出错:"+err.Error(), http.StatusBadRequest)
	return
}

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):

infile, header, err := r.FormFile(&quot;file&quot;)
if err != nil {
	http.Error(w, &quot;Error parsing uploaded file: &quot;+err.Error(), http.StatusBadRequest)
	return
}

// THIS IS VERY INSECURE! DO NOT DO THIS!
outfile, err := os.Create(&quot;./uploaded/&quot; + header.Filename)
if err != nil {
	http.Error(w, &quot;Error saving file: &quot;+err.Error(), http.StatusBadRequest)
	return
}

_, err = io.Copy(outfile, infile)
if err != nil {
	http.Error(w, &quot;Error saving file: &quot;+err.Error(), http.StatusBadRequest)
	return
}

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:

确定