学习
实践
活动
工具
TVP
写文章

Mongodb 文件存储之 GridFs

什么是GridFS

GridFS是一种大型文件存储在MongoDB的文件规范,所有官方支持的驱动都实现了GridFS,GridFS是MongoDB中的一个内置功能。可以保存文件。

为什么要使用GridFS

问题一

问题一:用FTP上传文件,把文件地址保存到MySql数据库,与GridFS有什么区别。答:文件系统到了后期会相当的难以管理,同时不利于扩展,此外做分布式文件系统也会显的很不容易,但是GridFS正好相反,基于MongoDB的文件系统,更加便于管理和扩展。

问题二

问题二:普通文件系统对于大文件处理相当麻烦,需要考虑文件系统自身的限制,GridFS提供了什么好方案。答:GridFS 会把大文件对象分割多个小的chunk,一般为256k/块,每块chunk都将会作为很大的内容文件,此外GridFS和MongoDB的分片可以实现分配到多个服务器上,并且没有增加操作的复杂性。

问题三

问题三:可以把二进制文件保存在MongoDB中吗?答:MongoDB默认的文件大小上限为16MB,所以超过了16MB,就应该使用GridFS。

GridFS的两个集合

GridFS使用两个集合保存一个文件,fs.files与fs.chunks。可以使用下面的命令查看

show collections

fs.files集合包含了文件的元数据,使用命令查看

db.fs.files.findOne();

将会返回如下的内容

{

"_id" : ObjectId("57fb553ac7fa9102e0000001"),

"chunkSize" : 261120,

"uploadDate" : ISODate("2016-10-10T08:45:50.051Z"),

"length" : 1.53513e+008,

"md5" : "9222e097e624800fdd9bfb568169ccad",

"filename" : "E:/jdk-7u79-linux-x64.tar.gz"

}

fs.chunks集合保存的是256KB尺寸进行分割的文件块,如果有分片的集合,可以分到多台服务器上。

db.fs.chunks.getIndexes();

以下是上传完成文件以后的集合文档

{

"0" : {

"v" : 1,

"key" : {

"_id" : 1

},

"name" : "_id_",

"ns" : "gridfs.fs.chunks"

},

"1" : {

"v" : 1,

"key" : {

"files_id" : 1,

"n" : 1

},

"name" : "files_id_1_n_1",

"ns" : "gridfs.fs.chunks"

}

}

GridFS 基本操作

上传文件

使用GridFS的put命令保存文件。输入如下的命令,实现文件的上传

mongofiles.exe -d gridfs put E:\elasticsearch-1.7.0.zip

列出清单

使用命令查看数据库中的文件的文档

db.fs.files.find()

返回的内容为

/* 1 */

{

"_id" : ObjectId("57fb553ac7fa9102e0000001"),

"chunkSize" : 261120,

"uploadDate" : ISODate("2016-10-10T08:45:50.051Z"),

"length" : 1.53513e+008,

"md5" : "9222e097e624800fdd9bfb568169ccad",

"filename" : "E:/jdk-7u79-linux-x64.tar.gz"

}

/* 2 */

{

"_id" : ObjectId("57fb6c49c7fa9135d4000001"),

"chunkSize" : 261120,

"uploadDate" : ISODate("2016-10-10T10:24:09.654Z"),

"length" : 3.17848e+007,

"md5" : "882013a3d205289dddce22c904d3c476",

"filename" : "E:\\elasticsearch-1.7.0.zip"

}

查找文件

输入文件的id,可以查看到文件的数据值

db.fs.chunks.find({files_id:ObjectId('57fb553ac7fa9102e0000001')});

以上实例,将会返回50个文档的数据

下载文件

使用get命令下载文件

mongofiles.exe -d gridfs get E:\elasticsearch-1.7.0.zip

Java操作GridFS

添加相关的maven

org.mongodb

mongo-java-driver

3.2.2

创建链接

public MongoDatabase mongoDatabase() throws Exception{

MongoClient mongoClient = new MongoClient(mongoHost, mongoPort);

return mongoClient.getDatabase(dbName);

}

上传文件

@Test

public void upload() throws Exception {

// 获取文件流

File file = new File("E:/zookeeper-3.4.8.tar.gz");

InputStream in = new FileInputStream(file);

// 创建一个容器,传入一个`MongoDatabase`类实例db

GridFSBucket bucket = GridFSBuckets.create(mongoDatabase());

// 上传

ObjectId fileId = bucket.uploadFromStream(UUID.randomUUID().toString(), in);

System.out.println("上传完成。 文件ID:"+fileId);

}

查找文件

@Test

public void findOne() throws Exception {

// 获取文件ID

String objectId = "57fbaffcec773716ecc54ef4";

// 创建一个容器,传入一个`MongoDatabase`类实例db

GridFSBucket bucket = GridFSBuckets.create(mongoDatabase());

// 获取内容

GridFSFindIterable gridFSFindIterable = bucket.find(Filters.eq("_id", new ObjectId(objectId)));

GridFSFile gridFSFile = gridFSFindIterable.first();

System.out.println("filename: " + gridFSFile.getFilename());

}

下载文件

@Test

public void download() throws Exception {

// 获取文件ID

String objectId = "57fbaffcec773716ecc54ef4";

// 获取文件流

File file = new File("D:/zookeeper-3.4.8.tar.gz");

// 创建一个容器,传入一个`MongoDatabase`类实例db

GridFSBucket bucket = GridFSBuckets.create(mongoDatabase());

// 创建输出流

OutputStream os = new FileOutputStream(file);

// 下载

bucket.downloadToStream(new ObjectId(objectId), os);

System.out.println("下载完成。");

}

删除文件

@Test

public void delete() throws Exception {

// 获取文件ID

String objectId = "57fbaffcec773716ecc54ef4";

// 创建一个容器,传入一个`MongoDatabase`类实例db

GridFSBucket bucket = GridFSBuckets.create(mongoDatabase());

// 删除

bucket.delete(new ObjectId(objectId));

System.out.println("删除完成。");

}

总结

使用GridFS可以作为文件的存储之一,可以进行使用。也算是一个解决方案

小明菜市场

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200713A0WHCF00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券