专栏首页流浪猫的golanggolang mongoDB GridFS查询 存储 删除文件

golang mongoDB GridFS查询 存储 删除文件

先讲一下 GridFS的作用

GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等),如果没有超过16m大小可以将数据保存在BSON数据中。 GridFS 也是文件存储的一种方式,但是它是存储在MonoDB的集合中。

GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/个,每个chunk将作为MongoDB的一个文档(document)被存储在chunks集合中。

GridFS 用两个集合来存储一个文件:fs.files与fs.chunks。 每个文件的实际内容被存在chunks(二进制数据)中,和文件有关的meta数据(filename,content_type,还有用户自定义的属性)将会被存在files集合中。 官方文档中还有这么两句话: GridFS is useful not only for storing files that exceed 16 MB but also for storing any files for which you want access without having to load the entire file into memory. See also When to Use GridFS. GridFS是可以存储任何你想要存储的文件,不仅仅是那些超过16M文件,意思是什么文件都能存。

Furthermore, if your files are all smaller the 16 MB BSON Document Size limit, consider storing the file manually within a single document instead of using GridFS. You may use the BinData data type to store the binary data. 此外,如果您的文件全部小于16 MB bson文档大小限制,请考虑将文件手动存储在单个文档中,而不是使用gridfs。您可以使用bindata数据类型来存储二进制数据。

第一步:先用命令行的方式存储一下,方便演示,我选一个音乐21M大小 在windows 的mongoDB安装平台下:与mongo.exe,mongod.exe 所在目录存在一个mongofiles.exe 命令行的方式进入,执行下面命令就可以:

mongofiles.exe -h 127.0.0.1  -d gridfs put Test.mkv

意思是向127.0.0.1的数据库gridfs添加Test.mkv 视频文件 参数说明: –d 指定数据库 ,默认是fs,Mongofiles list –d testGridfs -u –p 指定用户名,密码 -h 指定主机 -port 指定主机端口 -c 指定集合名,默认是fs -t 指定文件的MIME类型,默认会忽略 查看一下。 使用mongoDB的数据库工具“MongoDB Compass”查看数据

数据库中增加一个gridfs数据库,里面多了2个集合,分别为fs.chunks或者fs.files

打开fs.files可以看到数据库中有2个文件一个叫做something.mp3 一个Test.mkv,Test.mkv是我刚刚上传的。 上传的数据存在fs.chunks中,文件信息存储在fs.files中。

现在开始用golang代码操作了: 下载刚才存储的视频:还原到本地 。我选一个something.mp3 进行下载。 package main

import (
    "fmt"
    "gopkg.in/mgo.v2"

    "log"
    "os"
    "io"
)

func main() {
    session, err := mgo.Dial("mongodb://127.0.0.1:27017")
    defer session.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
    names, err := session.DatabaseNames();
    if err != nil {
        fmt.Println("未查询到数据库名字:", err)
    }
    fmt.Println(names)
    //通过文件名获取mp3
    file, err := session.DB("gridfs").GridFS("fs").Open("someThing.mp3")
    if err !=nil {
        fmt.Println(err)
        return
    }
    out, _ := os.OpenFile("E:\\test\\something.mp3.", os.O_CREATE, 0666)
    _,err = io.Copy(out, file)
    check(err)
    err = file.Close()
    check(err)
    //
    //b := make([]byte, 8192)
    //n, err := file.Read(b)
    //check(err)
    //fmt.Println(string(b))
    //check(err)
    //err = file.Close()
    //check(err)
    //fmt.Printf("%d bytes read\n", n)
}
func check(err error){
    log.Print(err)
}

运行结果:可以直接将something.mp3 下载到本地。

保存上传操作: 将something.mp3 改名字为 my.mp3 保存到gridfs

func upload(){
    session, err := mgo.Dial("mongodb://127.0.0.1:27017")
    defer session.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
    names, err := session.DatabaseNames();
    if err != nil {
        fmt.Println("未查询到数据库名字:", err)
    }
    fmt.Println(names)
    //通过文件名创建mp3
    file, err := session.DB("gridfs").GridFS("fs").Create("my.mp3")
    if err !=nil {
        fmt.Println(err)
        return
    }
    out, _ := os.OpenFile("E:\\test\\something.mp3.", os.O_RDWR, 0666)
    _,err = io.Copy(file, out)
    check(err)
    err = file.Close()
    check(err)
    err=out.Close()
    check(err)
}

运行结果

文件的删除操作

//直接利用名字移除
err = session.DB("gridfs").GridFS("fs").Remove("my.mp3")
    if err !=nil {
        fmt.Println(err)
    }else {
        fmt.Print("刪除成功")
    }

文件的查询操作

func ReadAll()  {
    session, err := mgo.Dial("mongodb://127.0.0.1:27017")
    defer session.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
    names, err := session.DatabaseNames();
    if err != nil {
        fmt.Println("未查询到数据库名字:", err)
    }
    fmt.Println(names)
    //通过文件名获取mp3
    gfs := session.DB("gridfs").GridFS("fs");
    iter := gfs.Find(nil).Iter()

    result:=new(fileinfo)
    for iter.Next(&result) {
        fmt.Println("一个一个输出:", result)
    }

}
type fileinfo struct {
    //文件大小
    LENGTH int32
    //md5
    MD5 string
    //文件名
    FILENAME string
}

func check(err error){
    log.Print(err)
}

运行结果: 一个一个输出: &{3963133 e58d3babaa101a57876c4b59945dd274 someThing.mp3} 一个一个输出: &{68113996 f79616b9e7dab89c9a0985349fd3ad10 Test.mkv}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • go Http Post 发送文件流

    水滴石穿。这里把Go Http Post 参数的函数也贴了处理主要对比两者不同之处。

    地球流浪猫
  • go的入门之路 http Get Post请求

       defer 关键字是总会执行,类似于java try catch finally 代码块

    地球流浪猫
  • golang mongoDB 的集合创建以及增删改查操作

    mongo官方没有golang 的官方驱动,但是有一个社区驱动: http://labix.org/mgo api文档:https://godoc.or...

    地球流浪猫
  • 聊聊kingbus的startMasterServer

    -Run方法接收请求,然后通过c.dispatch(c.ctx, data)进行分发

    codecraft
  • 聊聊kingbus的startMasterServer

    -Run方法接收请求,然后通过c.dispatch(c.ctx, data)进行分发

    codecraft
  • 《Network Programming with Go》阅读重点备忘(一)

    jeremyxu
  • 49. 访问PostgreSQL数据库增删改查 | 厚土Go学习笔记

    PostgreSQL是常见的免费的大型关系型数据库,具有丰富的数据类型,也是软件项目常用的数据库之一。 因其可靠的稳定性,通常我们可以拿它来做Oracle的替代...

    李海彬
  • Go 语言操作 MySQL 之 CURD 操作

    友情提示:此篇文章大约需要阅读 10分钟 52秒,不足之处请多指教,感谢你的阅读。

    Debug客栈
  • 如何批量删除k8s资源对象

    在云平台开发、中间件容器化时,经常会遇到批量删除k8s资源对象的需求,下面记录一下kubectl和golang发送删除pvc、pv、pod请求的例子,便于后续学...

    我的小碗汤
  • go语言path/filepath包之Walk源码解析

    go语言的path/filepath包包提供了很多兼容各个操作系统的文件路径实用操作方法,今天只来看看Walk方法:

    我的小碗汤

扫码关注云+社区

领取腾讯云代金券