1. GridFS介绍

GridFSMongoDB提供的用于持久化存储文件的模块,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:27017
database: 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 {
@Autowired
GridFsTemplate gridFsTemplate; @Test
public 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");
//得到文件ID
String 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; @Bean
public 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 {
@Autowired
GridFsTemplate gridFsTemplate; @Autowired
GridFSBucket gridFSBucket; @Test
public 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 {
@Autowired
GridFsTemplate gridFsTemplate; //删除文件
@Test
public void testDelFile() throws IOException {
//根据文件id删除fs.files和fs.chunks中的记录
gridFsTemplate.delete(Query.query(Criteria.where("_id").is("5dfd851306322e6b12057a40")));
} }

GridFS文件操作的更多相关文章

  1. 【.NET深呼吸】Zip文件操作(1):创建和读取zip文档

    .net的IO操作支持对zip文件的创建.读写和更新.使用起来也比较简单,.net的一向作风,东西都准备好了,至于如何使用,请看着办. 要对zip文件进行操作,主要用到以下三个类: 1.ZipFile ...

  2. 野路子出身PowerShell 文件操作实用功能

    本文出处:http://www.cnblogs.com/wy123/p/6129498.html 因工作需要,处理一批文件,本想写C#来处理的,后来想想这个是PowerShell的天职,索性就网上各种 ...

  3. Node基础篇(文件操作)

    文件操作 相关模块 Node内核提供了很多与文件操作相关的模块,每个模块都提供了一些最基本的操作API,在NPM中也有社区提供的功能包 fs: 基础的文件操作 API path: 提供和路径相关的操作 ...

  4. 归档NSKeyedArchiver解归档NSKeyedUnarchiver与文件管理类NSFileManager (文件操作)

    ========================== 文件操作 ========================== 一.归档NSKeyedArchiver 1.第一种方式:存储一种数据. // 归档 ...

  5. SQL Server附加数据库报错:无法打开物理文件,操作系统错误5

    问题描述:      附加数据时,提示无法打开物理文件,操作系统错误5.如下图: 问题原因:可能是文件访问权限方面的问题. 解决方案:找到数据库的mdf和ldf文件,赋予权限即可.如下图: 找到mdf ...

  6. 通过cmd完成FTP上传文件操作

    一直使用 FileZilla 这个工具进行相关的 FTP 操作,而在某一次版本升级之后,发现不太好用了,连接老是掉,再后来完全连接不上去. 改用了一段时间的 Web 版的 FTP 工具,后来那个页面也 ...

  7. Linux文件操作的主要接口API及相关细节

    操作系统API: 1.API是一些函数,这些函数是由linux系统提供支持的,由应用层程序来使用,应用层程序通过调用API来调用操作系统中的各种功能,来干活 文件操作的一般步骤: 1.在linux系统 ...

  8. C语言的fopen函数(文件操作/读写)

    头文件:#include <stdio.h> fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为:    FILE * fopen(const char * path, c ...

  9. Python的文件操作

    文件操作,顾名思义,就是对磁盘上已经存在的文件进行各种操作,文本文件就是读和写. 1. 文件的操作流程 (1)打开文件,得到文件句柄并赋值给一个变量 (2)通过句柄对文件进行操作 (3)关闭文件 现有 ...

随机推荐

  1. 如何使用PHP排序key为字母+数字的数组

    你还在为如何使用PHP排序字母+数字的数组而烦恼吗? 今天有个小伙伴在群里问: 如何将一个key为字母+数字的数组按升序排序呢? 举个例子: $test = [ 'n1' => 22423, ' ...

  2. Linux网络编程五、套接字超时

    1.accept超时 accept等待并接受连接请求的过程是阻塞的,可以通过IO转接来设置等待一定的时长,如果超时没有连接,就让这个函数返回,让当前进程/线程处理别的任务. 例: // 最大的文件描述 ...

  3. Android学习_MVC与Adapter

    一.           MVC模式 MVC模式代表Model-View-Controller(模型-视图-控制器)模式.这种模式用于应用程序的分层开发. Model(模型):代表一个存取数据的对象或 ...

  4. 创建express项目(nodejs)

    1.下载nodejs安装包 nodejs官网下载最新版本就行,网址:http://nodejs.cn/download/,点击自己适用的系统,自动下载跟电脑操作系统位数符合的安装包, 2.配置环境 最 ...

  5. linux下编译利用CMakeLists.txt 编译C++写的opencv程序

    https://hihozhou.com/blog/2017/05/11/linux-compile-opencv-c++-file.html cmake . make -j8

  6. Java中的<< 和 >> 和 >>> 分析理解

    Java中的<< 和 >> 和 >>> 详细分析 <<表示左移移,不分正负数,低位补0: 注:以下数据类型默认为byte-8位 左移时不管正负,低 ...

  7. yum 保存下载的rpm 包

    yum 保存下载的rpm 包 1 [root@bogon pluginconf.d]# vim /etc/yum.conf [main]cachedir=/var/cache/yum/$basearc ...

  8. 真正解决方案:phpMyAdmin #1089 - Incorrect prefix key; the storage engine doesn't support unique prefix key

    先直接给解决方案: 点击A_I后,不要输入大小,直接点击执行!!! 分析 当你在使用phpMyAdmin 创建数据库表的时候,一般我们需要设置一个主键,然后让其自增长,但是有时候当你设置完成后,你可能 ...

  9. GCC4.7+中如何替代C11中的_Generic

    C11标准中,一个非常重大的特性更新就是增加了Generic Selection这个特性.这个特性能使得C11支持轻量级的泛型编程,使得可以把一组具有不同类型而却有相同功能的函数抽象为一个接口. 对于 ...

  10. webpy简单入门---1

    1. 2. 3. 4.