MongoDB GridFS 存储大文件

时间:2023-01-06 21:00:56

我们经常会遇到这样的场景:上传/下载文件。

有两种思路可以解决这个问题:

(1)将文件存储在服务器的文件系统中;

(2)将文件存储在数据库中。

如果我们选择(2),那么我们可以使用MongoDB GridFS 用于存储大小超过 16MB 的文件(文档,压缩文件,音视频,软件)。

一、MongoDB GridFS 介绍

MongoDB GridFS 是一个分布式文件系统,可用于存储/检索大小超过 16MB 的文件。

内部实现:将文件分割为一个个 chunk (默认大小为 255KB)进行存储。

两个优点:

(1)可以存储大文件(超过 16MB);

(2)可以从文件的中间位置访问文件。

二、代码示例

 public class FileService {

     // 返回DB
private DB getDB() {
// ...
} /* 根据getDB()返回的DB新建一个GridFS实例并返回
* 这个GridFS实例用于上传、下载、删除、查找文件。
*/
private GridFS getGridFS() {
return new GridFS(getDB(), "自己定义的collection名");
} /**
* 保存类型为MultipartFile的文件
*
* @param multipartFile
* @throws IOException
*/
public void saveOne(final MultipartFile multipartFile) throws IOException {
saveOne(multipartFile.getInputStream(), multipartFile.getOriginalFilename()); } /**
* 保存类型为java.io.File的文件
*
* @param file
* @throws IOException
*/
public void saveOne(final File file) throws IOException {
saveOne(new FileInputStream(file), file.getName());
} public void saveOne(final InputStream in, final String fileName) {
GridFSInputFile gridFSInputFile = getGridFS().createFile(in);
gridFSInputFile.setFilename(fileName);
gridFSInputFile.save(); } /**
* 查询所有已上传的文件
*
* @return
*/
public Object queryAllFile() {
List<GridFSDBFile> result = getGridFS().find((DBObject) null);
List<Map<String, Object>> finalResult = new ArrayList<>();
Map<String, Object> map = null;
for (GridFSDBFile file : result) {
map = new HashMap<>();
map.put("id", ((ObjectId) file.getId()).toHexString());
map.put("fileName", file.getFilename());
map.put("length", file.getLength());
finalResult.add(map); }
return finalResult;
} /**
* 查询指定id的文件
*
* @param hexStringId
* 十六进制的id
* @return
*/
public GridFSDBFile queryOne(final String hexStringId) {
GridFSDBFile file = getGridFS().findOne(new ObjectId(hexStringId));
return file; } /**
* 删除给定id的文件
*
* @param hexStringId
*/
public void removeOne(final String hexStringId) {
getGridFS().remove(new ObjectId(hexStringId));
}
}

代码比较简单,就不做过多说明了。