专栏首页猿天地spring-data-mongodb之gridfs

spring-data-mongodb之gridfs

mongodb除了能够存储大量的数据外,还内置了一个非常好用的文件系统。 基于mongodb集群的优势,GridFS当然也是分布式的,而且备份也方便。 当用户把文件上传到GridFS后,文件会被分割成大小为256KB的块,并单独存放。

好处如下:

  1. 可以有Replication;
  2. 可以利用MongoDB的权限访问控制;
  3. 可以利用现成的MongoDB备份方式;

今天主要是学习如何使用data这个框架来操作GridFS,首先配置gridFs的模板类

<!-- Mongodb gridFs的模板 -->
 <bean id="gridFsTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
     <constructor-arg ref="mongoDbFactory" />
     <constructor-arg ref="mappingConverter" />
 </bean>
/**
  * 上传文件
  * @author yinjihuan
  * @throws Exception
  */
 public static void uploadFile() throws Exception {
     File file = new File("/Users/yinjihuan/Downlaods/logo.png");
     InputStream content = new FileInputStream(file);     //存储文件的额外信息,比如用户ID,后面要查询某个用户的所有文件时就可以直接查询
     DBObject metadata = new BasicDBObject("userId", "1001");
     GridFSFile gridFSFile = gridFsTemplate.store(content, file.getName(), "image/png", metadata);
     String fileId = gridFSFile.getId().toString();
     System.out.println(fileId);
 }

文件默认是上传到数据中的fs.files和fs.chunks中 files是用来存储文件的信息,文件名,md5,文件大小,还有刚刚的metadata,上传时间等等数据,数据格式如下:

{
    "_id": ObjectId("57c17bb0d4c666b6e53ba795"),
    "metadata": {
        "user_id": 1001
    },
    "filename": "file",
    "aliases": null,
    "chunkSize": NumberLong(261120),
    "uploadDate": ISODate("2016-09-08T11:38:24.999Z"),
    "length": NumberLong(165253),
    "contentType": "image/png",
    "md5": "668727a643ddd6df2e98f164d9fc90fd"
}

chunks则是用来存储文件内容的

  1. files_id就是文件的ID,也就是files集合中的_id
  2. n是文件块的索引,通常文件会被分割成256KB的块大小存储
  3. data就是文件的数据了

当需要访问文件的时候通过文件ID可以找到文件被分成了多少块,然后从第一块按顺序开始读取,返回给用户。

{    
    "_id": ObjectId("57c18993d4c6355ffeb6f8ae"),    
    "files_id": ObjectId("57c17bb0d4c666b6e53ba795"),    
    "n": 0,    
    "data": BinData(0,    "iVBORw0KGgDSDDSDDSD5xNvmxT5/sHLl5oDl/Y/NtznsPTPllg9+Gqie+Yj5xNvmxT5/sHLl5oDl/Y/NtznsPTPllg9+Gqie+YjoA")
}
{   
    "_id": ObjectId("57c18993d4c6355ffeb6f8ae"),    
    "files_id": ObjectId("57c17bb0d4c666b6e53ba795"),    
    "n": 1,    
    "data": BinData(1,    "iVBORw0KGgDSDDSDDSD5xNvmxT5/sHLl5oDl/Y/NtznsPTPllg9+Gqie+Yj5xNvmxT5/sHLl5oDl/Y/NtznsPTPllg9+Gqie+YjoA")
}
/**
  * 根据文件ID查询文件
  * @author yinjihuan
  * @param fileId
  * @return
  * @throws Exception
  */
 public static GridFSDBFile getFile(String fileId) throws Exception {     
    return gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));
 }
/**
  * 根据文件ID删除文件
  * @author yinjihuan
  * @param fileId
  * @throws Exception
  */
 public static void removeFile(String fileId) throws Exception {
     gridFsTemplate.delete(Query.query(Criteria.where("_id").is(fileId)));
 }

如果在Spring mvc中想直接访问存储的文件也很简单,直接通过文件ID查询该文件,然后直接输出到response就是了,记得要设置ContentType,这时就明白为什么存储的时候要把ContentType存起来了。

/**
  * 访问图片
  * @author yinjihuan
  * @param fileId
  * @param request
  * @param response
  */
 @RequestMapping(value = "/image/{fileId}")
 @ResponseBody public void getImage(@PathVariable String fileId, HttpServletResponse response) {     try {
         GridFSDBFile gridfs = filesService.getFile(fileId);
         response.setContentType(gridfs.getContentType());
         OutputStream out = response.getOutputStream();
         gridfs.writeTo(out);         
         out.flush();         
         out.close();
     } catch (Exception e) {
         e.printStackTrace();
     }
 }

本文分享自微信公众号 - 猿天地(cxytiandi)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-09-09

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • API加密框架Monkey-Api-Encrypt发布1.2版本

    monkey-api-encrypt 是我之前写的一个 API 加密的框架,主要是将加密/解密的逻辑交给框架实现,等数据到达 Controller 后自动解密了...

    猿天地
  • Hystrix 超时配置

    前阵子在我的知识星球中,有位朋友对我提了个问题,问我如何让Hystrix支持对接口级别的超时配置,今天给大家写篇文章,普及下Hystrix配置超时的几种方式。

    猿天地
  • 一向低调的小伙放了个大招,搞定了微服务接口单测依赖问题

    在微服务架构中,服务之间的依赖是很常见的事情。在开发过程中都是并行开发的,前端会依赖后端的接口,后端也有可能会依赖其他后端服务的接口。

    猿天地
  • Python中 文件处理

    py3study
  • 10.2 打开与关闭文件

    例如:fopen(“a1”,“r”),表示要打开名字为“a1”的文件,使用文件方式为“读入”。

    小林C语言
  • 10.2 C语言打开与关闭文件

    例如:fopen(“a1”,“r”),表示要打开名字为“a1”的文件,使用文件方式为“读入”。

    小林C语言
  • 【阿里算法专家】深度学习将业界技术迭代提升100倍,GraphDL 应用广阔

    【新智元导读】IJCAI 2018 现场,阿里妈妈以 Ad Tech 为主题举办了 Workshop,阿里妈妈资深算法专家朱小强、高级算法专家林伟,分享了将深度...

    新智元
  • unix环境高级编程(上)-文件篇

    笔者将《unix环境高级编程》主要内容总结为三篇:文件篇,进程篇,高级io和进程间通信三大板块。本文是unix环境高级编程系列文章第一篇:文件篇。该篇主要包括:

    kinnylee
  • python打开文件的方式有哪些

    就可以打开一个文件进行操作。第二个参数为对文件的操作方式,’w’是写文件,已存在的同名文件会被清空,不存在则会创建一个;’r’是读取文件,不存在会报错;’a’是...

    砸漏
  • Python 之文件读写操作

            使用 open 打开文件后,格式:open(filename,mode),最后一定要调用文件对象的 close() 方法,如图所示:

    py3study

扫码关注云+社区

领取腾讯云代金券