文件存储服务-spring-file-storage

1.1 简介

开源项目spring-file-storage,在 SpringBoot 中通过简单的方式将文件存储到 本地、FTP、SFTP、WebDAV、谷歌云存储、阿里云OSS、华为云OBS、七牛云Kodo、腾讯云COS、百度云 BOS、又拍云USS、MinIO、 AWS S3、金山云 KS3、美团云 MSS、京东云 OSS、天翼云 OOS、移动云 EOS、沃云 OSS、 网易数帆 NOS、Ucloud US3、青云 QingStor、平安云 OBS、首云 OSS、IBM COS、其它兼容 S3 协议的平台。

在这里插入图片描述

1.2 架构图

在这里插入图片描述

1.3 实现逻辑

1、核心实现逻辑是定义文件存储接口FileStorage,在FileStorage内抽象若干功能方法,目前支持的功能包括获取云服务商平台、设置平台、保存文件、上传文件、删除文件、下载文件、下载缩略图文件、 释放相关资源等,后各存储服务提供商根据其SDK实现对应方法。
在这里插入图片描述

@Getter
@Setter
public class AliyunOssFileStorage implements FileStorage {
    /* 存储平台 */
    private String platform;
    private String accessKey;
    private String secretKey;
    private String endPoint;
    private String bucketName;
    private String domain;
    private String basePath;
    private OSS client;
    
    // 封装实现ossSDK
    public boolean save(FileInfo fileInfo, UploadPretreatment pre) {
    
    }
}

2、除此之外,还定义了多个切面调用链,支持在文件上传、下载、删除等过程中输出相关日志信息,只需要实现FileStorageAspect接口就可以自定义切面,并支持动态增减切面。
在这里插入图片描述
在这里插入图片描述

//获得切面 List
CopyOnWriteArrayList<FileStorageAspect> list = fileStorageService.getAspectList();

//增加
FileStorageAspect aspect = new LogFileStorageAspect();
list.add(aspect);

//删除
list.remove(aspect);

//条件删除
list.removeIf(item -> item instanceof LogFileStorageAspect);

3、支持文件元数据管理:除了文件内容本身,还可以存储一些与文件相关的元数据信息,例如文件名称、大小、上传时间等。设计时可以考虑使用数据库或索引服务来存储和管理这些元数据,以方便文件的检索和管理。
在这里插入图片描述

@Service
public class FileDetailService extends ServiceImpl<FileDetailMapper,FileDetail> implements FileRecorder {
    /**
     * 保存文件信息到数据库
     */
    @SneakyThrows
    @Override
    public boolean record(FileInfo info) {
        FileDetail detail = BeanUtil.copyProperties(info,FileDetail.class,"attr");
        //这是手动获 取附加属性字典 并转成 json 字符串,方便存储在数据库中
        if (info.getAttr() != null) {
            detail.setAttr(new ObjectMapper().writeValueAsString(info.getAttr()));
        }
       
        boolean b = save(detail);
        if (b) {
            info.setId(detail.getId());
        }
        return b;
    }
}

1.4 项目分析

优点:

  1. 扩展性强:可支持动态扩展市面绝大部分云服务存储提供商,切换成本小
  2. 使用简单:集成方便,只需要引入云存储依赖、spring-file-storage依赖、配置相关信息即可使用

缺点:
3. 文件上传、下载都是在后端实现,接口效率受服务器内存、带宽限制,对大文件上传/下载不友好
4. 不支持临时文件链接的获取,前端无法根据生成的已授权的文件地址直接put上传文件

测试数据:

文件上传MinIOOSS
30MB1.2秒131秒
206MB6秒230秒
2.34GB67秒-
文件下载MinIOOSS
30MB1秒35秒
206MB2秒330秒
2.34GB26秒-

1.5 项目集成

1. 引入pom依赖

<dependency>
    <groupId>com.nimbus</groupId>
    <artifactId>spring-file-storage</artifactId> <!--已封装好主要云存储服务商的依赖-->
    <version>0.7.0</version>
</dependency>
  1. yaml自定义存储服务提供商
spring:
  file-storage: #文件存储配置
    default-platform: aliyun-oss-1    # 默认使用的存储平台
    thumbnail-suffix: ".min.jpg"      # 缩略图后缀,例如【.min.jpg】【.png】
    local-plus: # 本地存储
      - platform: local-plus-1        # 存储平台标识
        enable-storage: true          # 启用存储
        enable-access: true           # 启用访问(线上请使用 Nginx 配置,效率更高)
        domain: "D:/Temp/"            # 访问域名,例如:“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
        base-path: local-plus/        # 基础路径
        path-patterns: /**            # 访问路径
        storage-path: D:/Temp/        # 存储路径 D:\Temp
    aliyun-oss: # 阿里云 OSS
      - platform: aliyun-oss-1        # 存储平台标识
        enable-storage: true          # 启用存储
        access-key: ${aliyun.oss.access_key}
        secret-key: ${aliyun.oss.access_secret}
        end-point: ${aliyun.oss.endpoint}
        bucket-name: ${aliyun.oss.bucket_name}
        domain: ${aliyun.oss.host}             # 访问域名,注意“/”结尾
        base-path: infra-common/               # 基础路径
    minio: # MinIO
      - platform: minio-1
        enable-storage: true
        access-key: ??
        secret-key: ??
        end-point: ??
        bucket-name: ??
        domain: ??
        base-path: hy/

3. 表设计

-- mysql
DROP TABLE IF EXISTS `file_detail`;
CREATE TABLE `file_detail`
(
    `id`                int(10) UNSIGNED                                        NOT NULL AUTO_INCREMENT COMMENT '文件id',
    `url`               varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '文件访问地址',
    `size`              bigint(20)                                              NULL DEFAULT NULL COMMENT '文件大小,单位字节',
    `filename`          varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件名称',
    `original_filename` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '原始文件名',
    `base_path`         varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '基础存储路径',
    `path`              varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '存储路径',
    `ext`               varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT '文件扩展名',
    `content_type`      varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT 'MIME类型',
    `platform`          varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT '存储平台',
    `th_url`            varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '缩略图访问路径',
    `th_filename`       varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '缩略图名称',
    `th_size`           bigint(20)                                              NULL DEFAULT NULL COMMENT '缩略图大小,单位字节',
    `th_content_type`   varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT '缩略图MIME类型',
    `object_id`         varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT '文件所属对象id',
    `object_type`       varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT '文件所属对象类型,例如用户头像,评价图片',
    `attr`              text CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT '附加属性',
    `create_time`       datetime(0)                                             NULL DEFAULT NULL COMMENT '创建时间',
    PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  CHARACTER SET = utf8
  COLLATE = utf8_general_ci COMMENT = '文件记录表'
  ROW_FORMAT = Dynamic;


-- postgre 自定义
create table if not exists "file_detail" (
    id VARCHAR(255) not null,
    url VARCHAR(255) not null,
    "size" BIGINT null,
    filename VARCHAR(255) null,
    original_filename VARCHAR(255) null,
    base_path VARCHAR(255) null,
    "path" VARCHAR(255) null,
    ext VARCHAR(255) null,
    content_type VARCHAR(255) null,
    platform VARCHAR(255) null,
    th_url VARCHAR(255) null,
    th_filename VARCHAR(255) null,
    th_size bigint null,
    th_content_type VARCHAR(255) null,
    object_id VARCHAR(255) null,
    object_type VARCHAR(255) null,
    attr VARCHAR(255) null,
    create_time TIMESTAMP null,
    project_id UUID null,
    tenant_id UUID null,
    primary key ("id")
    );

-- Column comments
COMMENT ON TABLE file_detail IS '文件记录表';
COMMENT ON COLUMN public.file_detail.id IS '主键';
COMMENT ON COLUMN public.file_detail.url IS '文件访问地址';
COMMENT ON COLUMN public.file_detail."size" IS '文件大小,单位字节';
COMMENT ON COLUMN public.file_detail.filename IS '文件名称';
COMMENT ON COLUMN public.file_detail.original_filename IS '原始文件名';
COMMENT ON COLUMN public.file_detail.base_path IS '基础存储路径';
COMMENT ON COLUMN public.file_detail."path" IS '存储路径';
COMMENT ON COLUMN public.file_detail.ext IS '文件扩展名';
COMMENT ON COLUMN public.file_detail.content_type IS 'MIME类型';
COMMENT ON COLUMN public.file_detail.platform IS '存储平台';
COMMENT ON COLUMN public.file_detail.th_url IS '缩略图访问路径';
COMMENT ON COLUMN public.file_detail.th_filename IS '缩略图名称';
COMMENT ON COLUMN public.file_detail.th_size IS '缩略图大小,单位字节';
COMMENT ON COLUMN public.file_detail.th_content_type IS '缩略图MIME类型';
COMMENT ON COLUMN public.file_detail.object_id IS '文件所属对象id';
COMMENT ON COLUMN public.file_detail.object_type IS '文件所属对象类型,例如用户头像,评价图';
COMMENT ON COLUMN public.file_detail.attr IS '附加属性';
COMMENT ON COLUMN public.file_detail.create_time IS '创建时间';
COMMENT ON COLUMN public.file_detail.project_id IS '项目id';
COMMENT ON COLUMN public.file_detail.tenant_id IS '租户id';
``
  • 13
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你可以使用Java中的MultipartFile类将上传的文件存储到本地。下面是一个示例代码,演示了如何将MultipartFile文件保存到本地目录中: ```java import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; public class FileStorageService { private String uploadDir; // 本地存储目录 public void storeFile(MultipartFile file) { try { // 获取文件名 String fileName = file.getOriginalFilename(); // 创建目标文件路径 Path targetLocation = Path.of(uploadDir, fileName); // 将文件复制到目标路径 Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { // 处理异常 } } } ``` 在这个示例中,首先你需要在你的项目中引入Spring Web模块,以便使用MultipartFile类。 然后,你需要创建一个FileStorageService类,其中包含一个storeFile方法。此方法接受一个MultipartFile参数,表示上传的文件。它将获取文件名,并使用原始文件名创建目标文件路径。 最后,通过调用Files.copy方法,将文件从MultipartFile对象的输入流复制到目标路径。通过指定StandardCopyOption.REPLACE_EXISTING选项,如果目标路径已存在同名文件,则会被替换。 记得设置好存储目录的路径(uploadDir),确保该目录存在并有写入权限。 希望这个示例能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr朱墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值