我们经常会遇到这样的场景:上传/下载文件。
有两种思路可以解决这个问题:
(1)将文件存储在服务器的文件系统中;
(2)将文件存储在数据库中。
如果我们选择(2),那么我们可以使用MongoDB GridFS 用于存储大小超过 16MB 的文件(文档,压缩文件,音视频,软件)。
一、MongoDB GridFS 介绍
MongoDB GridFS 是一个分布式文件系统,可用于存储/检索大小超过 16MB 的文件。
内部实现:将文件分割为一个个 chunk (默认大小为 255KB)进行存储。
两个优点:
(1)可以存储大文件(超过 16MB);
(2)可以从文件的中间位置访问文件。
二、代码示例
1 public class FileService { 2 3 // 返回DB 4 private DB getDB() { 5 // ... 6 } 7 8 /* 根据getDB()返回的DB新建一个GridFS实例并返回 9 * 这个GridFS实例用于上传、下载、删除、查找文件。 10 */ 11 private GridFS getGridFS() { 12 return new GridFS(getDB(), "自己定义的collection名"); 13 } 14 15 /** 16 * 保存类型为MultipartFile的文件 17 * 18 * @param multipartFile 19 * @throws IOException 20 */ 21 public void saveOne(final MultipartFile multipartFile) throws IOException { 22 saveOne(multipartFile.getInputStream(), multipartFile.getOriginalFilename()); 23 24 } 25 26 /** 27 * 保存类型为java.io.File的文件 28 * 29 * @param file 30 * @throws IOException 31 */ 32 public void saveOne(final File file) throws IOException { 33 saveOne(new FileInputStream(file), file.getName()); 34 } 35 36 public void saveOne(final InputStream in, final String fileName) { 37 GridFSInputFile gridFSInputFile = getGridFS().createFile(in); 38 gridFSInputFile.setFilename(fileName); 39 gridFSInputFile.save(); 40 41 } 42 43 /** 44 * 查询所有已上传的文件 45 * 46 * @return 47 */ 48 public Object queryAllFile() { 49 List<GridFSDBFile> result = getGridFS().find((DBObject) null); 50 List<Map<String, Object>> finalResult = new ArrayList<>(); 51 Map<String, Object> map = null; 52 for (GridFSDBFile file : result) { 53 map = new HashMap<>(); 54 map.put("id", ((ObjectId) file.getId()).toHexString()); 55 map.put("fileName", file.getFilename()); 56 map.put("length", file.getLength()); 57 finalResult.add(map); 58 59 } 60 return finalResult; 61 } 62 63 /** 64 * 查询指定id的文件 65 * 66 * @param hexStringId 67 * 十六进制的id 68 * @return 69 */ 70 public GridFSDBFile queryOne(final String hexStringId) { 71 GridFSDBFile file = getGridFS().findOne(new ObjectId(hexStringId)); 72 return file; 73 74 } 75 76 /** 77 * 删除给定id的文件 78 * 79 * @param hexStringId 80 */ 81 public void removeOne(final String hexStringId) { 82 getGridFS().remove(new ObjectId(hexStringId)); 83 } 84 }
代码比较简单,就不做过多说明了。