英文:
GoLang send file via POST request
问题
我是你的中文翻译助手,以下是翻译好的内容:
我是Go语言的新手,我想创建一个用于文件上传的REST API Web服务器...
所以我在主函数(文件上传)中遇到了问题,通过POST请求将文件上传到我的服务器...
我有以下代码来调用上传函数:
router.POST("/upload", UploadFile)
这是我的上传函数:
func UploadFile(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
io.WriteString(w, "Upload files\n")
postFile(r.Form.Get("file"), "/uploads")
}
func postFile(filename string, targetUrl string) error {
bodyBuf := &bytes.Buffer{}
bodyWriter := multipart.NewWriter(bodyBuf)
// 这一步非常重要
fileWriter, err := bodyWriter.CreateFormFile("file", filename)
if err != nil {
fmt.Println("error writing to buffer")
return err
}
// 打开文件句柄
fh, err := os.Open(filename)
if err != nil {
fmt.Println("error opening file")
return err
}
// 复制文件内容
_, err = io.Copy(fileWriter, fh)
if err != nil {
panic(err)
}
bodyWriter.FormDataContentType()
bodyWriter.Close()
return err
}
但是我在/upload/
目录中看不到任何上传的文件...
那么我做错了什么?
附注:我得到了第二个错误 error opening file
,所以我认为文件上传或从UploadFile
函数获取文件有问题,我是对的吗?如果是的话,我该如何将文件从这个函数传递到postFile
函数?
英文:
I am new in GoLang language, and I want to create REST API WebServer for file uploading...
So I am stuck in main function (file uploading) via POST request to my server...
I have this line for calling upload function
router.POST("/upload", UploadFile)
and this is my upload function:
func UploadFile( w http.ResponseWriter, r *http.Request, _ httprouter.Params ) {
io.WriteString(w, "Upload files\n")
postFile( r.Form.Get("file"), "/uploads" )
}
func postFile(filename string, targetUrl string) error {
bodyBuf := &bytes.Buffer{}
bodyWriter := multipart.NewWriter(bodyBuf)
// this step is very important
fileWriter, err := bodyWriter.CreateFormFile("file", filename)
if err != nil {
fmt.Println("error writing to buffer")
return err
}
// open file handle
fh, err := os.Open(filename)
if err != nil {
fmt.Println("error opening file")
return err
}
//iocopy
_, err = io.Copy(fileWriter, fh)
if err != nil {
panic(err)
}
bodyWriter.FormDataContentType()
bodyWriter.Close()
return err
}
but I can't see any uploaded files in my /upload/
directory...
So what am I doing wrong?
P.S I am getting second error => error opening file
, so I think something wrong in file uploading or getting file from UploadFile
function, am I right? If yes, than how I can teancfer or get file from this function to postFile
function?
答案1
得分: 4
multipart.Writer
生成多部分消息,这不是你想用来接收客户端文件并将其保存到磁盘的工具。
假设你正在从客户端(例如浏览器)上传文件,使用的是 Content-Type: application/x-www-form-urlencoded
,你应该使用 FormFile 而不是 r.Form.Get
。FormFile
返回一个 *multipart.File
值,其中包含客户端发送的文件内容,你可以使用 io.Copy
或其他方法将该内容写入磁盘。
英文:
The multipart.Writer
generates multipart messages, this is not something you want to use for receiving a file from a client and saving it to disk.
Assuming you're uploading the file from a client, e.g. a browser, with Content-Type: application/x-www-form-urlencoded
you should use FormFile instead of r.Form.Get
which returns a *multipart.File
value that contains the content of the file the client sent and which you can use to write that content to disk with io.Copy
or what not.
答案2
得分: 3
os.Open
将打开一个文件,由于文件不存在,你将会得到一个错误。
使用os.Create
代替,它将创建一个新文件并打开它。(参考:https://golang.org/pkg/os/#Open)
func Open
func Open(name string) (*File, error)
Open函数打开一个指定名称的文件进行读取。如果成功,返回的文件对象可以用于读取;关联的文件描述符的模式为O_RDONLY。如果出现错误,将会是*PathError类型的错误。
func Create
func Create(name string) (*File, error)
Create函数使用0666模式(在umask之前)创建一个指定名称的文件,如果文件已经存在,则截断它。如果成功,返回的文件对象可以用于I/O操作;关联的文件描述符的模式为O_RDWR。如果出现错误,将会是*PathError类型的错误。
编辑
创建了一个新的处理程序作为示例:
还使用了OpenFile,如此处所述:https://stackoverflow.com/questions/45541656/golang-send-file-via-post-request/45541764?noredirect=1#comment78043634_45541764
func Upload(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "上传文件\n")
file, handler, err := r.FormFile("file")
if err != nil {
panic(err) //请不要这样做
}
defer file.Close()
// 复制示例
f, err := os.OpenFile(handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
panic(err) //请不要这样做
}
defer f.Close()
io.Copy(f, file)
}
英文:
os.Open
will open a file, since the file doesn't exist you will get an error.
Use os.Create
instead it will create a new file and open it. (ref: https://golang.org/pkg/os/#Open)
> func Open
> func Open(name string) (*File, error)
> Open opens the named file for
> reading. If successful, methods on the returned file can be used for
> reading; the associated file descriptor has mode O_RDONLY. If there is
> an error, it will be of type *PathError.
> func Create
>
> func Create(name string) (*File, error)
>
> Create creates the named file with mode 0666 (before umask),
> truncating it if it already exists. If successful, methods on the
> returned File can be used for I/O; the associated file descriptor has
> mode O_RDWR. If there is an error, it will be of type *PathError.
EDIT
Made a new handler as an example:
And also using OpenFile as mentioned by: https://stackoverflow.com/questions/45541656/golang-send-file-via-post-request/45541764?noredirect=1#comment78043634_45541764
func Upload(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Upload files\n")
file, handler, err := r.FormFile("file")
if err != nil {
panic(err) //dont do this
}
defer file.Close()
// copy example
f, err := os.OpenFile(handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
panic(err) //please dont
}
defer f.Close()
io.Copy(f, file)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论