在MongoDB GridFS中存储上传的文件使用mgo而不保存到内存 [英] Store Uploaded File in MongoDB GridFS Using mgo without Saving to Memory
问题描述
在功能上它工作正常。但是,在我的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屋!