springboot整合fastdfs上传下载文件代码

一、添加依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--fastdfs-->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

二、配置yml

server:
  port: 6666
spring:
  profiles:
    active: dev
  application:
    name: API-SETTING
  main:
    allow-bean-definition-overriding: true
  servlet:
    # 文件大小配置
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB
http:
  #最大连接数
  maxTotal: 100
  #并发数
  defaultMaxPerRoute: 20
  #创建连接的最长时间
  connectTimeout: 1000
  #从连接池中获取到连接的最长时间
  connectionRequestTimeout: 500
  #数据传输的最长时间
  socketTimeout: 10000
  #提交请求前测试连接是否可用
  staleConnectionCheckEnabled: true
  #https证书路径
  keyStorePath: .keystore
  #证书密码
  keyStorepass: ehe.aaa.admin 
fdfs:
  tracker-list: # tracker地址,ip端口改一下
    - 11.11.11.1:8080
  so-timeout: 1501
  connect-timeout: 601
  thumb-image: # 缩略图
    width: 200
    height: 200

三、controller


/**
 * 文件上传下载 controller
 * @author jerry
 */
@Api(value = "文件传输", tags = "文件传输")
@RequestMapping("/file")
public interface FileController {

    /**
     * 上传
     * @param file 文件
     * @return 文件路径
     * @throws IOException 异常
     */
    @ApiOperation(value = "上传", notes = "上传")
    @PostMapping("/upload")
    ResponseInfo<String> upload(MultipartFile file) throws IOException;

    /**
     * 上传并返回文件路径和文件名
     * @param file 文件
     * @return 文件路径
     * @throws IOException 异常
     */
    @ApiOperation(value = "上传并返回文件路径和文件名", notes = "上传并返回文件路径和文件名")
    @PostMapping("/upload/info")
    ResponseInfo<Map<String, String>> uploadAndInfo(MultipartFile file) throws IOException;

    /**
     * 获取缩略图路径
     * @param fullPath 文件路径
     * @return 缩略图路径
     */
    @ApiOperation(value = "缩略图路径", notes = "缩略图路径")
    @GetMapping("/thumbImagePath")
    ResponseInfo<String> getThumbImagePath(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath);

    /**
     * 下载
     * @param fullPath 文件路径
     * @param response 请求响应
     * @throws IOException 异常
     */
    @ApiOperation(value = "下载", notes = "下载")
    @GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    void download(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath, HttpServletResponse response) throws IOException;

    /**
     * 删除
     * @param fullPath 文件路径
     */
    @ApiOperation(value = "删除", notes = "删除")
    @DeleteMapping("/delete")
    void delete(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath);

    /**
     * 下载缩略图
     * @param fullPath 文件路径
     * @param response 请求响应
     * @throws IOException 异常
     */
    @ApiOperation(value = "下载缩略图", notes = "下载缩略图")
    @GetMapping(value = "/download/thunimage", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    void downloadThubImagePath(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath, HttpServletResponse response) throws IOException;
    }

service

/**
 * 文件上传下载 controller
 * @author jerry
 */
@Slf4j
@RestController
public class FileControllerImpl implements FileController {

    /** 文件服务器 客户端 */
    @Autowired
    private FastFileStorageClient storageClient;

    /** 缩略图 配置 */
    @Autowired
    private ThumbImageConfig thumbImageConfig;

    /** 文件名称 */
    private static final String META_DATA_NAME_FILE_NAME = "FILE_NAME";

    @Autowired
    private FileService fileService;

    @Override
    public ResponseInfo<String> upload(MultipartFile file) throws IOException {
        Map<String, String> result = fileService.uploadFile(file);
        return ResponseInfo.ofOk("上传成功!", result.get("uri"));
    }

    @Override
    public ResponseInfo<Map<String, String>> uploadAndInfo(MultipartFile file) throws IOException {
        Map<String, String> result = fileService.uploadFile(file);
        return ResponseInfo.ofOk("上传成功!", result);
    }

    @Override
    public ResponseInfo<String> getThumbImagePath(@RequestParam String fullPath) {
        StorePath storePath = StorePath.parseFromUrl(fullPath);
        return ResponseInfo.ofOk(HttpResponseStatus.SC_OK.getMessage(), thumbImageConfig.getThumbImagePath(storePath.getFullPath()));
    }

    @Override
    public void  download(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath, HttpServletResponse response) throws IOException {
        StorePath storePath = StorePath.parseFromUrl(fullPath);
        Set<MetaData> metaDataSet = storageClient.getMetadata(storePath.getGroup(), storePath.getPath());
        String fileName = metaDataSet.stream().findFirst()
                .filter(metaData -> META_DATA_NAME_FILE_NAME.equals(metaData.getName()))
                .map(MetaData::getValue)
                .orElse(FilenameUtils.getName(fullPath));
        byte[] bytes = storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());

        response.reset();
        response.setContentType("multipart/form-data;charset=UTF-8;");
        fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        try (OutputStream outputStream = response.getOutputStream()) {
            outputStream.write(bytes);
        }
    }

    @Override
    public void delete(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath) {
        storageClient.deleteFile(fullPath);
    }

    /**
     * 下载缩略图
     * @param fullPath 文件路径
     * @param response 请求响应
     * @throws IOException
     */
    @Override
    public synchronized void downloadThubImagePath(String fullPath, HttpServletResponse response) throws IOException {
        StorePath storePath = StorePath.parseFromUrl(fullPath);
        String path = thumbImageConfig.getThumbImagePath(storePath.getFullPath());
        this.download(path,response);
    }

 
}

serviceimpl

@Service
public class FileServiceImpl implements FileService {

    /** 图片后缀集合 */
    private static final Set<String> IMAGE_PREFIX_SET = Set.of("JPG", "JPEG", "PNG", "GIF", "BMP", "WBMP");

    /** 文件服务器 客户端 */
    @Autowired
    private FastFileStorageClient storageClient;

    /** 文件名称 */
    private static final String META_DATA_NAME_FILE_NAME = "FILE_NAME";

    @Override
    public Map<String, String> uploadFile(MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        String filePrefix = FilenameUtils.getExtension(fileName);
        StorePath storePath;
        if (IMAGE_PREFIX_SET.contains(filePrefix.toUpperCase())) {
            // 图片上传并且生成缩略图
            storePath = this.storageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), filePrefix, Collections.singleton(new MetaData(META_DATA_NAME_FILE_NAME, fileName)));
        } else {
            // 普通文件上传
            storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), filePrefix, Collections.singleton(new MetaData(META_DATA_NAME_FILE_NAME, fileName)));
        }
        Map<String, String> result = new HashMap<>();
        result.put("uri", storePath.getFullPath());
        result.put("name", fileName);
        return result;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
文本格式不能很好显示,请见谅(附件里有比较齐整的excel表格统计) 大小类型 传输类型 api方法 文件大小 花费时间 速率byte/ms 速率mb/s 缓存数组 次数 备注 大文件 下载 download_file(group_name, remote_filename, localFile) 1073741824(约1G) 28343ms 37883 36.12804413 无 1 下载 download_file(group_name, remote_filename , downloadStream) 1073741824(约1G) 29195ms 36778 35.07423401 0 1 fastDFS的DownloadStream,FileOutputStream 下载 download_file(group_name, remote_filename , downloadStream) 1073741824(约1G) 24352ms 44092 42.04940796 2K 1 fastDFS的DowloadStream,BufferedOutputStream 下载 download_file(group_name, remote_filename , DownloadCallback) 1073741824(约1G) 24831ms 43241 41.23783112 2K 1 实现DownloadCallback,BufferedOutputStream 下载 download_file(group_name, remote_filename , DownloadCallback) 1073741824(约1G) 25922ms 41422 39.50309753 8K 1 实现DownloadCallback,BufferedOutputStream 普通文件 下载 download_file(group_name, remote_filename, localFile) 59113472(约56M) 382ms 154747 147.5782394 无 1 下载 download_file(group_name, remote_filename , downloadStream) 59113472(约57M) 369ms 160199 152.7776718 0 1 fastDFS的DownloadStream,FileOutputStream 下载 download_file(group_name, remote_filename , downloadStream) 59113472(约58M) 499ms 118702 113.2030487 2K 1 fastDFS的DowloadStream,BufferedOutputStream 下载 download_file(group_name, remote_filename , DownloadCallback) 59113472(约59M) 592ms 99853 95.22724152 2K 1 实现DownloadCallback,BufferedOutputStream 下载建议:100M内数据使用fastDFS提供的DownloadStream;大于1G的数据,使用BufferedOutputStream和DowloadStream
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值