首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 实现 FastDFS 实现文件的上传、下载、删除

Java 实现 FastDFS 实现文件的上传、下载、删除

作者头像
create17
发布2020-03-12 15:52:55
3.2K0
发布2020-03-12 15:52:55
举报

最近在项目上完成了附件上传和下载功能,是用的 fastdfs 来实现的。好记性不如烂笔头,今天把关键代码记录下来,方便以后复用。

一、Base64 转 图片url

1)在 pom.xml 中添加依赖:
<!--fastdfs-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-fastdfs</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
2)在 application.yml 中添加 fastdfs 相关配置:
fdfsIp: http://fastdfs:8880/

fastdfs:
  connecttimeout-in-seconds: 5
  network-timeout-in-seconds: 10
  charset: UTF-8
  # token 防盗链功能
  http-anti-steal-token: false
  # 密钥
  http-secret-key: FastDFS1234567890
  # TrackerServer port
  http-tracker-http-port: 8888
  # 测试环境
  tracker-server-list:
    - fastdfs:22122

示例代码:

上述方法就是将图片的 base64 码进行转换并上传到了 fastdfs 上。以下是可复制粘贴的源码:

import org.springframework.fasfdfs.exception.FdfsException;
import org.springframework.fasfdfs.server.FastDFSClient;

@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Value("${fdfsIp}")
    private String fdfsIp;

    @Autowired
    private FastDFSClient fastDFSClient;

    /**
     * 保存用户信息
     *
     * @param userDto DTO 对象
     * @return success/fail
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveUser(UserDTO userDto) {

        // 图片base64转换为图片url
        String imgBase64 = userDto.getAvatar();
        if (!StrUtil.isBlank(imgBase64)) {
            String imageUri = null;
            try {
                imageUri = fdfsIp + fastDFSClient.uploadFileWithBase64(imgBase64, ".jpg");
            } catch (FdfsException e) {
                log.error("图片上传fastdfs异常", e);
            }
            if (StrUtil.isBlank(imageUri)) {
                log.info("图片转换失败!");
                return false;
            }
            userDto.setAvatar(imageUri);
        }

        // ...
    }
}   

二、文件(word、pdf)上传到 fastdfs

关于像 word、pdf 这样的文件上传到 fastdfs,我是通过 fastdfs-client-java 这个 jar 包来实现:

1)在 pom.xml 文件中添加依赖:
<dependency>
    <groupId>org.csource</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>1.27-SNAPSHOT</version>
</dependency>
2)添加 fastdfs_client.conf 文件
#jar中使用时需要将此文件名修改为fastdfs_client.conf 。
#也可以在jar被调用方resource下加入fastdfs_client.conf 内容如下
connect_timeout = 60
network_timeout = 120
charset = UTF-8
http.tracker_http_port = 8888
http.anti_steal_token = no
http.secret_key = FastDFS1234567890

tracker_server =fastdfs:22122
3)相关代码实现
fastdfs 文件属性相关:
@Data
public class FastDFSFile implements Serializable {

    private static final long serialVersionUID = 2637755431406080379L;

    /**
     * 文件二进制
     */
    private byte[] content;

    /**
     * 文件名称
     */
    private String name;

    /**
     * 文件长度
     */
    private Long size;

    public FastDFSFile(byte[] content, String name, Long size){
        this.content = content;
        this.name = name;
        this.size = size;
    }
}
fastdfs 工具类相关(包含初始化 fatdfs 连接,上传、下载、删除文件):

图片版

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.io.IOException;
import java.io.Serializable;

/**
 * @author liuyzh
 * @description fastdfs上传文件,参考链接:https://blog.wuwii.com/fsds-java.html
 * @date 2020-03-03
 */
@Slf4j
public class FastDFSUtils implements Serializable {

    private static final long serialVersionUID = -4462272673174266738L;
    private static TrackerClient trackerClient;
    private static TrackerServer trackerServer;
    private static StorageClient1 storageClient1;

    static {
        try {
            //clientGloble读配置文件
            ClientGlobal.init("fastdfs_client.conf");
            //trackerclient
            trackerClient = new TrackerClient();
            trackerServer = trackerClient.getConnection();
            //storageclient
            storageClient1 = new StorageClient1(trackerServer, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * fastDFS文件上传
     *
     * @param file 上传的文件 FastDFSFile
     * @return String 返回文件的绝对路径
     */
    public static String uploadFile(FastDFSFile file) {
        String path = null;
        try {
            //文件扩展名
            String ext = FilenameUtils.getExtension(file.getName());
            //mata list是表文件的描述
            NameValuePair[] mata_list = new NameValuePair[3];
            mata_list[0] = new NameValuePair("fileName", file.getName());
            mata_list[1] = new NameValuePair("fileExt", ext);
            mata_list[2] = new NameValuePair("fileSize", String.valueOf(file.getSize()));
            path = storageClient1.upload_file1(file.getContent(), ext, mata_list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return path;
    }

    /**
     * fastDFS文件下载
     *
     * @param groupName      组名
     * @param remoteFileName 文件名
     * @param specFileName   真实文件名
     * @return ResponseEntity<byte [ ]>
     */
    public static ResponseEntity<byte[]> downloadFile(String groupName, String remoteFileName, String specFileName) {
        byte[] content = null;
        HttpHeaders headers = new HttpHeaders();
        try {
            content = storageClient1.download_file(groupName, remoteFileName);
            headers.setContentDispositionFormData("attachment", new String(specFileName.getBytes("UTF-8"), "iso-8859-1"));
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseEntity<byte[]>(content, headers, HttpStatus.CREATED);
    }

    /**
     * 删除fastdfs文件
     * @param storagePath 文件的全部路径 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
     * @return -1失败,0成功
     * @throws IOException
     * @throws Exception
     */
    public static Boolean deleteFile(String storagePath) {
        int result = -1;
        try {
            result = storageClient1.delete_file1(storagePath);
        } catch (IOException | MyException e) {
            log.error("fastdfs删除文件异常:", e);
        }
        if (result == -1) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 根据fastDFS返回的path得到文件的组名
     * @param path fastDFS返回的path
     * @return
     */
    public static String getGroupFormFilePath(String path){
        return path.split("/")[0];
    }

    /**
     * 根据fastDFS返回的path得到文件名
     * @param path fastDFS返回的path
     * @return
     */
    public static String getFileNameFormFilePath(String path) {
        return path.substring(path.indexOf("/")+1);
    }
}
上传代码示例:
@Override
@SneakyThrows
public R uploadFile(MultipartFile file) {

    JSONObject jsonObject = new JSONObject();
    try {
        Long fileSize = file.getSize();
        // 检查文件大小,不能超过5M
        if (fileSize >= 5 * 1024 * 1024) {
            return R.failed("附件大小不允许超过5M");
        }
        String attachmentName = file.getOriginalFilename();
        FastDFSFile fastDFSFile = new FastDFSFile(file.getBytes(), file.getOriginalFilename(), file.getSize());
        String attachmentPath = FastDFSUtils.uploadFile(fastDFSFile);

        jsonObject.put("attachmentPath", attachmentPath);
        jsonObject.put("attachmentName", attachmentName);
        jsonObject.put("attachmentSize", OtherUtil.getFileSizeUnit(fileSize));
        return R.ok(jsonObject);
    } catch (IOException e) {
        log.info("上传附件异常:", e);
    }
    return R.failed("附件上传异常");
}
下载代码示例(两种):
  • 方式一:
/**
 * 案件所属附件下载
 * 接口 demo:http://192.168.166.189:7700/case/download?path=group1/M00/03/CF/wKinzF5d-EOAWPuEAAGjUNtaNqM02.docx
 *
 * @param path fastdfs返回的路径
 * @return
 */
@RequestMapping(value = "/download")
public ResponseEntity<byte[]> download(String path) {

    // 根据附件url获取附件名称
    AttachmentInfo attachmentInfo = attachmentInfoService.getAttachmentInfoByUrl(path);
    // 下载后的文件名称
    String specFileName = attachmentInfo.getFileName();

    String filename = FastDFSUtils.getFileNameFormFilePath(path);
    String group = FastDFSUtils.getGroupFormFilePath(path);
    return FastDFSUtils.downloadFile(group, filename, specFileName);
}

这样就可以实现浏览器下载了。不过还可以用 nginx 的方式来完成文件的下载:

  • 方式二:

在 nginx 的 fastdfs 相关 server 配置里面添加:

if ($arg_attname ~* .(doc|docx|txt|pdf|zip|rar|xls|xlsx|png|jpeg|jpg)$) {
    add_header Content-Disposition "attachment;filename=$arg_attname";
}

如下图所示:

重启 nginx 后,这样就可以通过访问 url 来进行文件下载了。

比如:http://fastdfs:8880/group1/M00/03/CF/wKinzF5d-EOAWPuEAAGjUNtaNqM02.docx?attname=测试.docx

删除代码示例:
/**
 * @param storagePath 文件的全部路径 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
 * @return -1失败,0成功
 * @throws IOException
 * @throws Exception
 */
public static Boolean deleteFile(String storagePath) {
    int result = -1;
    try {
        result = storageClient1.delete_file1(storagePath);
    } catch (IOException | MyException e) {
        log.error("fastdfs删除文件异常:", e);
    }
    if (result == -1) {
        return false;
    } else {
        return true;
    }
}

三、小结

关于 fastdfs 的文件上传、下载、删除的示例代码上面都已经介绍清楚了,如果有小伙伴遇到了 fastdfs jar 包的依赖问题,也不要慌,我已经踩过坑了,出坑记录:实操:Could not autowire No beans of 'FastDFS Client' type found 的解决方法 ,可以看这篇。

热 文 推 荐

Ambari 2.7.3.0 安装部署 hadoop 3.1.0.0 集群视频完整版

【实战】使用 Kettle 工具将 mysql 数据增量导入到 MongoDB 中

都快2020年了,ambari自定义服务集成,你还没掌握吗?文末有福利

HBase原理(一):架构理解

HBase二次开发之搭建HBase调试环境,如何远程debug HBase源代码

Kafka消费者 之 指定位移消费

Kylin配置Spark并构建Cube(修订版)

☞ 看完您如果还不明白 Kerberos 原理,算我输

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据实战演练 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Base64 转 图片url
    • 1)在 pom.xml 中添加依赖:
      • 2)在 application.yml 中添加 fastdfs 相关配置:
      • 二、文件(word、pdf)上传到 fastdfs
        • 1)在 pom.xml 文件中添加依赖:
          • 2)添加 fastdfs_client.conf 文件
            • 3)相关代码实现
              • fastdfs 文件属性相关:
              • fastdfs 工具类相关(包含初始化 fatdfs 连接,上传、下载、删除文件):
              • 上传代码示例:
              • 下载代码示例(两种):
              • 删除代码示例:
          • 三、小结
          相关产品与服务
          TDSQL MySQL 版
          TDSQL MySQL 版(TDSQL for MySQL)是腾讯打造的一款分布式数据库产品,具备强一致高可用、全球部署架构、分布式水平扩展、高性能、企业级安全等特性,同时提供智能 DBA、自动化运营、监控告警等配套设施,为客户提供完整的分布式数据库解决方案。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档