在MongoDB GridFS中存储上传的文件使用mgo而不保存到内存 [英] Store Uploaded File in MongoDB GridFS Using mgo without Saving to Memory

查看:335
本文介绍了在MongoDB GridFS中存储上传的文件使用mgo而不保存到内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

noob Golang和Sinatra人在这里。我已经破解了Sinatra应用程序,接受从HTML表单发布的上传文件,并通过GridFS将其保存到托管的MongoDB数据库中。这似乎工作正常。我正在使用mgo驱动程序在Golang中编写相同的应用程序。

在功能上它工作正常。但是,在我的Golang代码中,我将文件读入内存,然后使用mgo将文件从内存写入MongoDB。这看起来比我等同的Sinatra应用程序慢得多。我了解到Rack和Sinatra之间的交互不会执行这个中间或临时步骤。



以下是我的Go代码片段:

  func uploadfilePageHandler(w http.ResponseWriter,req * http.Request){
// Capture多部分形式的文件信息
file,handler,err:= req.FormFile(filename)
if err!= nil {
fmt.Println(err)
}

//将文件读入内存
data,err:= ioutil.ReadAll(file)
// ...检查err值为零

//指定Mongodb数据库
my_db:= mongo_session.DB(...数据库名称...)

//在Mongodb Gridfs实例中创建文件
my_file,err:= my_db.GridFS(fs)。Create(unique_filename)
// ...检查err值为零

//将文件写入Mongodb Gridfs实例
n,err:= my_file.Write(data)
// ...检查err值为零

//关闭文件
err = my_file.Close()
// ...检查err值是否为

//写入日志类型消息
fmt .Printf(%d个字节写入Mongodb实例\ n,n)

// ...其他语句重定向到用户流的其余部分...
}

问题


  • 是否需要这个临时步骤( data,err:= ioutil.ReadAll(file))?

  • 如果是这样,我可以更有效地执行此步骤吗?

  • 是否有其他可接受的做法或方法我应该考虑? b $ b


感谢...

解决方案

不应该立即在内存中完全读取文件,因为文件太大会导致文件中断。 GridFS.Create文档中的第二个例子避免了这个问题:

  file,err:= db.GridFS(fs)。Create(myfile.txt)
check(err)
messages,err:= os.Open(/ var / log / messages)
check(err)
推迟messages.Close()
err = io.Copy(file ,消息)
check(err)
err = file.Close()
check(err)

至于为什么它比其他东西慢,很难说,没有深入探讨这两种方法的细节。


noob Golang and Sinatra person here. I have hacked a Sinatra app to accept an uploaded file posted from an HTML form and save it to a hosted MongoDB database via GridFS. This seems to work fine. I am writing the same app in Golang using the mgo driver.

Functionally it works fine. However in my Golang code, I read the file into memory and then write the file from memory to the MongoDB using mgo. This appears much slower than my equivalent Sinatra app. I get the sense that the interaction between Rack and Sinatra does not execute this "middle" or "interim" step.

Here's a snippet of my Go code:

func uploadfilePageHandler(w http.ResponseWriter, req *http.Request) {
  // Capture multipart form file information
  file, handler, err := req.FormFile("filename")
  if err != nil {
    fmt.Println(err)
  }

  // Read the file into memory
  data, err := ioutil.ReadAll(file)
  // ... check err value for nil

  // Specify the Mongodb database
  my_db := mongo_session.DB("... database name...")

  // Create the file in the Mongodb Gridfs instance
  my_file, err := my_db.GridFS("fs").Create(unique_filename)
  // ... check err value for nil

  // Write the file to the Mongodb Gridfs instance
  n, err := my_file.Write(data)
  // ... check err value for nil

  // Close the file
  err = my_file.Close()
  // ... check err value for nil

  // Write a log type message
  fmt.Printf("%d bytes written to the Mongodb instance\n", n)

  // ... other statements redirecting to rest of user flow...
}

Question:

  • Is this "interim" step needed (data, err := ioutil.ReadAll(file))?
  • If so, can I execute this step more efficiently?
  • Are there other accepted practices or approaches I should be considering?

Thanks...

解决方案

No, you should not read the file entirely in memory at once, as that will break when the file is too large. The second example in the documentation for GridFS.Create avoids this problem:

file, err := db.GridFS("fs").Create("myfile.txt")
check(err)
messages, err := os.Open("/var/log/messages")
check(err)
defer messages.Close()
err = io.Copy(file, messages)
check(err)
err = file.Close()
check(err)

As for why it's slower than something else, hard to tell without diving into the details of the two approaches used.

这篇关于在MongoDB GridFS中存储上传的文件使用mgo而不保存到内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆