如何使用golang从mongodb提供文件

时间:2018-06-05 11:22:09

标签: mongodb go gridfs fileserver

我正在开展一个项目,我需要提供存储在mongodb中的文件。这些文件存储在GridF中。我使用gopkg.in/mgo.v2作为包来连接和查询数据库。

我可以从db中检索文件,这并不难。

f, err := s.files.OpenId(id)

但是如何用http提供该文件? 我使用JulienSchmidt路由器来处理所有其他restfull请求。 我发现的解决方案总是使用静态文件,而不是数据库中的文件。

提前致谢

2 个答案:

答案 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)

}