我正在开展一个项目,我需要提供存储在mongodb中的文件。这些文件存储在GridF中。我使用gopkg.in/mgo.v2作为包来连接和查询数据库。
我可以从db中检索文件,这并不难。
f, err := s.files.OpenId(id)
但是如何用http提供该文件? 我使用JulienSchmidt路由器来处理所有其他restfull请求。 我发现的解决方案总是使用静态文件,而不是数据库中的文件。
提前致谢
答案 0 :(得分:4)
提示:建议使用github.com/globalsign/mgo
代替gopkg.in/mgo.v2
(后者不再维护)。
mgo.GridFile
类型实现io.Reader
,因此您可以使用io.Copy()
将其内容复制到http.ResponseWriter
。
但由于mgo.GridFile
也实施io.Seeker
,您可以利用http.ServeContent()
。引用其文档:
ServeContent对io.Copy的主要好处是它正确处理Range请求,设置MIME类型,并处理If-Match,If-Unmodified-Since,If-None-Match,If-Modified-Since和If-Range请求。
提供文件的示例处理程序:
func serveFromDB(w http.ResponseWriter, r *http.Request) {
var gridfs *mgo.GridFS // Obtain GridFS via Database.GridFS(prefix)
name := "somefile.pdf"
f, err := gridfs.Open(name)
if err != nil {
log.Printf("Failed to open %s: %v", name, err)
http.Error(w, "something went wrong", http.StatusInternalServerError)
return
}
defer f.Close()
http.ServeContent(w, r, name, time.Now(), f) // Use proper last mod time
}
答案 1 :(得分:0)
它已经很旧了,但是我通过导入导入了goMongo驱动程序的另一个解决方案
"go.mongodb.org/mongo-driver/mongo/gridfs"
var bucket *gridfs.Bucket //creates a bucket
dbConnection, err := db.GetDBCollection() //connect db with your your
if err != nil {
log.Fatal(err)
}
bucket, err = gridfs.NewBucket(dbConnection)
if err != nil {
log.Fatal(err)
}
name := "br100_update.txt"
downloadStream, err := bucket.OpenDownloadStreamByName(name)
if err != nil {
log.Printf("Failed to open %s: %v", name, err)
http.Error(w, "something went wrong", http.StatusInternalServerError)
return
}
defer func() {
if err := downloadStream.Close(); err != nil {
log.Fatal(err)
}
}()
// Use SetReadDeadline to force a timeout if the download does not succeed in
// 2 seconds.
if err = downloadStream.SetReadDeadline(time.Now().Add(2 * time.Second)); err
!= nil {
log.Fatal(err)
}
//下面的代码用于读取文件
fileBuffer := bytes.NewBuffer(nil)
if _, err := io.Copy(fileBuffer, downloadStream); err != nil {
log.Fatal(err)
}