千家信息网

SpringBoot中怎么将文件上传至 FastDFS

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,SpringBoot中怎么将文件上传至 FastDFS,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、什么是FastD
千家信息网最后更新 2026年11月02日SpringBoot中怎么将文件上传至 FastDFS

SpringBoot中怎么将文件上传至 FastDFS,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

一、什么是FastDFS

FastDFS 是一个开源的轻量级分布式文件系统,它解决了大数据量存储和负载均衡等问题,特别适合以中小文件(建议范围:4 KB < file_size < 500 MB)为载体的在线服务,如相册网站、视频网站等

FastDFS 由 C 语言开发,支持 Linux、FreeBSD 等 UNIX 系统类 Google FS,不是通用的文件系统,只能通过专有 API 访问,目前提供了 C、Java 和 PHP API,为互联网应用量身定做,解决了大容量文件存储问题,追求高性能和高扩展性,FastDFS 可以看做是基于文件的 Key Value Pair 存储系统,称作分布式文件存储服务会更合适。

  1. FastDFS 特性

  • 文件不分块存储,上传的文件和 OS 文件系统中的文件一一对应

  • 支持相同内容的文件只保存一份,节约磁盘空间

  • 下载文件支持 HTTP 协议,可以使用内置 Web Server,也可以和其他 Web Server 配合使用

  • 支持在线扩容

  • 支持主从文件

  • 存储服务器上可以保存文件属性(meta-data)V2.0 网络通信采用 libevent,支持大并发访问,整体性能更好

  1. FastDFS 相关概念

FastDFS 服务端有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)

  • Tracker Server:跟踪服务器,主要做调度工作,起负载均衡的作用。在内存记录集群中所有存储组和存储服务器的状态信息,是客户端和数据服务器交互的枢纽。相比 GFS 中的 Master 更为精简,不记录文件索引信息,占用的内存量很少。

  • Storage Server:存储服务器(又称存储节点或数据服务器),文件和文件属性(Meta Data)都保存到存储服务器上。Storage Server 直接利用 OS 的文件系统调用管理文件。

  • Client:客户端,作为业务请求的发起方,通过专有接口,使用 TCP/IP 协议与跟踪器服务器或存储节点进行数据交互。FastDFS 向使用者提供基本文件访问接口,如 upload、download、append、delete 等,以客户端库的方式提供给用户使用。

Tracker 相当于 FastDFS 的大脑,不论是上传还是下载都是通过 Tracker 来分配资源;客户端一般可以使用 Ngnix 等静态服务器来调用或者做一部分的缓存;存储服务器内部分为卷(或者叫做组),卷与卷之间是平行的关系,可以根据资源的使用情况随时增加,卷内服务器文件相互同步备份,以达到容灾的目的。

  1. 上传机制

  • 首先客户端请求 Tracker 服务获取到存储服务器的 IP 地址和端口;

  • 然后客户端根据返回的 IP 地址和端口号请求上传文件;

  • 存储服务器接收到请求后生产文件,并且将文件内容写入磁盘并返回给客户端 file_id、路径信息、文件名等信息,客户端保存相关信息上传完毕。

  1. 下载机制

  • 客户端带上文件名信息请求 Tracker 服务获取到存储服务器的 IP 地址和端口;

  • 然后客户端根据返回的 IP 地址和端口号请求下载文件,存储服务器接收到请求后返回文件给客户端。

二、Spring Boot 集成 FastDFS

本节示例项目会在上一节项目的基础上进行构建开发,从前端上传文件到后台后,直接传递到 FastDFS 集群中,并返回文件存储的地址。

POM包配置

引入 FastDFS 的 Java 客户端:

    org.csource    fastdfs-client-java    1.27-SNAPSHOT

FastDFS配置

项目 resources 目录下添加fdfs_client.conf文件,配置文件设置了连接的超时时间、编码格式以及 tracker_server 地址等信息。

connect_timeout = 60 # 连接超时时间network_timeout = 60 # 网络超时时间charset = UTF-8 # 编码格式http.tracker_http_port = 8080 #tracker 端口http.anti_steal_token = no #token 防盗链功能http.secret_key = 123456 #密钥# tracer server 列表,多个 tracer server 的话,分行列出tracker_server = 192.168.53.85:22122tracker_server = 192.168.53.86:22122

封装 FastDFS 上传工具类

封装 FastDFSFile,文件基础信息包括文件名、内容、文件类型、作者等。

public class FastDFSFile {    private String name;    private byte[] content;    private String ext;    private String md5;    private String author;    //省略getter、setter}

接下来封装 FastDFSClient 类,FastDFSClient 主要封装最基础的操作,包含上传、下载、删除等方法。FastDFSFile 任务可以是 FastDFS 上传文件的封装,操作时每一个文件对应一个实例。

首先在类加载的时候读取配置信息,并进行初始化。

static {    try {        String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();        //ClientGlobal.init 方法会读取配置文件,并初始化对应的属性。        ClientGlobal.init(filePath);    } catch (Exception e) {        logger.error("FastDFS Client Init Fail!",e);    }}
  1. 文件上传

  • 使用 FastDFS 提供的客户端 storageClient 来进行文件上传,最后将上传结果返回。

public static String[] upload(FastDFSFile file) {    logger.info("File Name: " + file.getName() + "File Length:" + file.getContent().length);    //文件属性信息    NameValuePair[] meta_list = new NameValuePair[1];    meta_list[0] = new NameValuePair("author", file.getAuthor());    long startTime = System.currentTimeMillis();    String[] uploadResults = null;    StorageClient storageClient=null;    try {        //获取         storageClient = getStorageClient();        //上传        uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);    } catch (IOException e) {        logger.error("IO Exception when uploadind the file:" + file.getName(), e);    } catch (Exception e) {        logger.error("Non IO Exception when uploadind the file:" + file.getName(), e);    }    logger.info("upload_file time used:" + (System.currentTimeMillis() - startTime) + " ms");    //验证上传结果    if (uploadResults == null && storageClient!=null) {        logger.error("upload file fail, error code:" + storageClient.getErrorCode());    }    //上传文件成功会返回 groupName。    logger.info("upload file successfully!!!" + "group_name:" + uploadResults[0] + ", remoteFileName:" + " " + uploadResults[1]);    return uploadResults;}
  • NameValuePair,主要存储文件的一些基础属性,如作者信息、创建时间等;

  • getStorageClient(),封装了获取客户端的方法。

首先获取 TrackerServer 信息,使用 TrackerServer 构建出每次操作的客户端实例 StorageClient。详细代码如下:

private static StorageClient getStorageClient() throws IOException {    TrackerServer trackerServer = getTrackerServer();    StorageClient storageClient = new StorageClient(trackerServer, null);    return  storageClient;}

下面为封装获取 TrackerServer 的方法:

private static TrackerServer getTrackerServer() throws IOException {    TrackerClient trackerClient = new TrackerClient();    TrackerServer trackerServer = trackerClient.getConnection();    return  trackerServer;}
  1. 获取文件

根据 groupName 和文件名获取文件信息。group 也可称为卷,同组内服务器上的文件是完全相同的,同一组内的 storage server 之间是对等的,文件上传、删除等操作可以在任意一台 storage server 上进行。

public static FileInfo getFile(String groupName, String remoteFileName) {    try {        storageClient = new StorageClient(trackerServer, storageServer);        return storageClient.get_file_info(groupName, remoteFileName);    } catch (IOException e) {        logger.error("IO Exception: Get File from Fast DFS failed", e);    } catch (Exception e) {        logger.error("Non IO Exception: Get File from Fast DFS failed", e);    }    return null;}
  1. 下载文件

根据 storageClient 的 API 获取文件的字节流并返回:

public static InputStream downFile(String groupName, String remoteFileName) {    try {        StorageClient storageClient = getStorageClient();        byte[] fileByte = storageClient.download_file(groupName, remoteFileName);        InputStream ins = new ByteArrayInputStream(fileByte);        return ins;    } catch (IOException e) {        logger.error("IO Exception: Get File from Fast DFS failed", e);    } catch (Exception e) {        logger.error("Non IO Exception: Get File from Fast DFS failed", e);    }    return null;}
  1. 删除文件

根据文件名和组删除对应的文件;当使用 FastDFS 时,直接调用 FastDFSClient 对应的方法即可。

public static void deleteFile(String groupName, String remoteFileName)        throws Exception {    StorageClient storageClient = getStorageClient();    int i = storageClient.delete_file(groupName, remoteFileName);    logger.info("delete file successfully!!!" + i);}

编写上传控制类

从 MultipartFile 中读取文件信息,然后使用 FastDFSClient 将文件上传到 FastDFS 集群中,封装一个 saveFile() 方法用来调用上面封装的 FastDFS 工具类,将 MultipartFile 文件上传到 FastDFS 中,并返回上传后文件的地址信息。

public String saveFile(MultipartFile multipartFile) throws IOException {    String[] fileAbsolutePath={};    String fileName=multipartFile.getOriginalFilename();    String ext = fileName.substring(fileName.lastIndexOf(".") + 1);    byte[] file_buff = null;    InputStream inputStream=multipartFile.getInputStream();    if(inputStream!=null){        int len1 = inputStream.available();        file_buff = new byte[len1];        inputStream.read(file_buff);    }    inputStream.close();    FastDFSFile file = new FastDFSFile(fileName, file_buff, ext);    try {        fileAbsolutePath = FastDFSClient.upload(file);  //upload to fastdfs    } catch (Exception e) {        logger.error("upload file Exception!",e);    }    if (fileAbsolutePath==null) {        logger.error("upload file failed,please upload again!");    }    String path=FastDFSClient.getTrackerUrl()+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];    return path;}

当上传请求传递到后端时,调用上面方法 saveFile()。

@PostMapping("/upload") public String singleFileUpload(@RequestParam("file") MultipartFile file,                               RedirectAttributes redirectAttributes) {    if (file.isEmpty()) {        redirectAttributes.addFlashAttribute("message", "Please select a file to upload");        return "redirect:uploadStatus";    }    try {        String path=saveFile(file);        redirectAttributes.addFlashAttribute("message",                "You successfully uploaded '" + file.getOriginalFilename() + "'");        redirectAttributes.addFlashAttribute("path","file path url '" + path + "'");    } catch (Exception e) {        logger.error("upload file failed",e);    }    return "redirect:/uploadStatus";}

上传成功之后,将文件的路径展示到页面,效果图如下:

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

文件 服务 存储 服务器 客户 信息 客户端 封装 地址 方法 支持 系统 属性 文件名 配置 内容 基础 数据 时间 端口 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网佳科技有限公司 云信互联网科技有限公司 科技互联网龙头 互联网科技公司怎么样 剑昆互联网络科技有限公司临桂 河南猎农互联网科技有限公司 搜狐科技互联网 米聚互联网科技南京有限公司排面 畅思互联网科技 明优互联网科技有限公司 世界互联网领先科技成果获奖 伍佰万互联网科技怎么赚钱 深圳无忧互联网科技 富国互联网金融科技混合基金 35岁以上互联网科技行业 广州互联网高科技取餐柜 互联网科技包装股 福仕德教育科技互联网 上海互联网科技园景观 知域互联网科技有限公司官网 广州为想互联网科技有限公司 远信互联网科技 山东吉时兔互联网科技有限公司 剑昆互联网络科技有限公司临桂 港股科技和互联网 浙江互联网科技研学营 互联网方面的科技前沿 城市宝互联网科技有限公司 唯美互联网科技 上海互联网科技园景观
0