1. GridFS介绍
GridFS
是MongoDB
提供的用于持久化存储文件的模块,CMS
使用MongoDB
存储数据,使用GridFS
可以快速集成
开发。
它的工作原理是:
在GridFS
存储文件是将文件分块存储,文件会按照256KB的大小分割成多个块进行存储,GridFS
使用两个集合
(collection
)存储文件,一个集合是chunks
, 用于存储文件的二进制数据;一个集合是files
,用于存储文件的元数据信息(文件名称、块大小、上传时间等信息)。
从GridFS
中读取文件要对文件的各各块进行组装、合并。
详细参考:https://docs.mongodb.com/manual/core/gridfs/
2. GridFS 存取文件测试
2.1 新建项目配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo-monogo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo-monogo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
2.2 在application.yml
配置mongodb
spring:data:mongodb:uri: mongodb://root:root@localhost:27017database: xc_cms
2.3 GridFS
存取文件测试
1、存文件
使用GridFsTemplate
存储文件测试代码:
向测试程序注入GridFsTemplate
。
package com.example.demomonogo;import org.bson.types.ObjectId;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;@SpringBootTest
class DemoMonogoApplicationTests {@AutowiredGridFsTemplate gridFsTemplate;@Testpublic void testGridFs() throws FileNotFoundException {//要存储的文件File file = new File("D:\\test\\user_selected.png");//定义输入流FileInputStream inputStram = new FileInputStream(file);//向GridFS存储文件ObjectId objectId = gridFsTemplate.store(inputStram, "user_selected.png", "image/png");//得到文件IDString fileId = objectId.toString();System.out.println(fileId);}}
文件以及成功被存入到GridFS
2.4 读取文件
1)在config
包中定义Mongodb
的配置类,如下:
GridFSBucket
用于打开下载流对象
package com.example.demomonogo.config;/*** @author john* @date 2019/12/21 - 10:39*/import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MongoConfig {@Value("${spring.data.mongodb.database}")String db;@Beanpublic GridFSBucket getGridFSBucket(MongoClient mongoClient) {MongoDatabase database = mongoClient.getDatabase(db);GridFSBucket bucket = GridFSBuckets.create(database);return bucket;}
}
2)测试代码如下
package com.example.demomonogo;import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;@SpringBootTest
class DemoMonogoApplicationTests {@AutowiredGridFsTemplate gridFsTemplate;@AutowiredGridFSBucket gridFSBucket;@Testpublic void queryFile() throws IOException {String fileId = "5dfd851306322e6b12057a40";//根据id查询文件GridFSFile gridFSFile =gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));//打开下载流对象GridFSDownloadStream gridFSDownloadStream =gridFSBucket.openDownloadStream(gridFSFile.getObjectId());//创建gridFsResource,用于获取流对象GridFsResource gridFsResource = new GridFsResource(gridFSFile, gridFSDownloadStream);//获取流中的数据InputStream inputStream = gridFsResource.getInputStream();File f1 = new File("D:\\test\\get.png");if (!f1.exists()) {f1.getParentFile().mkdirs();}byte[] bytes = new byte[1024];// 创建基于文件的输出流FileOutputStream fos = new FileOutputStream(f1);int len = 0;while ((len = inputStream.read(bytes)) != -1) {fos.write(bytes, 0, len);}inputStream.close();fos.close();}}
2.5 删除文件
package com.example.demomonogo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;import java.io.IOException;@SpringBootTest
class DemoMonogoApplicationTests {@AutowiredGridFsTemplate gridFsTemplate;//删除文件@Testpublic void testDelFile() throws IOException {//根据文件id删除fs.files和fs.chunks中的记录gridFsTemplate.delete(Query.query(Criteria.where("_id").is("5dfd851306322e6b12057a40")));}}