Fastdfs介绍
FastDFS 是用 c 语言编写的一款开源的分布式文件系统。FastDFS 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务
使用Fastdfs环境介绍
- SpringMVC
- jdk1.7
前置要求
本次使用 fastdfs-client-java
sdk来实现文件的上传、下载、删除功能
1.下载fastdfs-client-java源码进行手动编译打包
源码下载地址:https://github.com/happyfish100/fastdfs-client-java
2.把下载的源码导入idea中并进行打包
打包时需要指定jdk版本,默认使用的时jdk1.6,这里我项目使用的是jdk1.8所以需要改成1.7,如果你们的是其他版本的jdk只需要改成对应的即可,高版本jdk未测试是否有用,需要小伙伴们自己测试下,这边只提供我测试正常的数据
也可以直接从我打包好的jar直接下载 fastdfs-client-java
打包文件放入maven或者私服
windows环境下把打好的包放入maven仓库 org/csource目录下:
如果使用的是Nexus私服,则需要上传即可,上传步骤如下:
SpringMVC项目Fastdfs使用
pom引入
<!--fastdfs文件上传-->
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27-SNAPSHOT</version>
</dependency>
fdfs_client.conf配置文件编写(文件内容行注释不要写在配置行后面否则会导致文件内容加载失败)
# fdfs client配置文件
connect_timeout = 60
network_timeout = 60
charset = UTF-8
http.tracker_http_port = 8080
tracker_server = 127.0.0.1:22122
FastDFSUtils.java工具类编写
package com.channel.utils;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
/**
* @author: LGJ
* @date: 2024/12/5 15:46
* @description: fdfs工具类
*/
public class FastDFSUtils {
private final static Logger logger = LoggerFactory.getLogger(FastDFSUtils.class);
private static TrackerClient trackerClient;
private static TrackerServer trackerServer;
private static StorageServer storageServer;
private static StorageClient storageClient;
private static final int GROUP_NAME_LENGTH = 6;
private static final int REMOTE_NAME_START_INDEX = 7;
static {
try {
String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
logger.info("加载FastDFS配置文件: {}", filePath);
ClientGlobal.init(filePath);
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageClient = new StorageClient(trackerServer, storageServer);
} catch (Exception e) {
logger.error("FastDFS 初始化失败:{}", e.getMessage());
}
}
/**
* 文件上传
* @param fileBytes 文件内容 字节
* @param ext 文件扩展名 png jpg jpeg等
*/
public static String upload(byte[] fileBytes, String ext) {
String[] uploadResults = null;
try {
uploadResults = storageClient.upload_file(fileBytes, ext, null);
} catch (Exception e) {
logger.error("文件上传失败:{}", e.getMessage());
}
if (uploadResults == null && storageClient != null) {
logger.error("上传文件错误,错误码: " + storageClient.getErrorCode());
}
assert uploadResults != null;
// 获取组名
String groupName = uploadResults[0];
// 获取文件存储路径
String remoteFileName = uploadResults[1];
logger.info("组名:{},文件存储路径:{}", groupName, remoteFileName);
// 格式:group1/M00/00/CF/CqIAH2dSrH6EYz_iAAAAAF4Tt3M202.png
return groupName + "/" +remoteFileName;
}
/**
* 删除文件
* @param remoteFileName 文件存储路径 参数格式 group1/M00/00/CF/*.png
*/
public static boolean deleteFile(String remoteFileName) {
try {
if (StringUtil.isEmpty(remoteFileName)){
logger.info("删除文件远程地址不能为空:{}", remoteFileName);
return false;
}
// 提取 groupName 和 remoteName
String groupName = remoteFileName.substring(0, GROUP_NAME_LENGTH);
String remoteName = remoteFileName.substring(REMOTE_NAME_START_INDEX);
// 调用 delete_file 方法
int result = storageClient.delete_file(groupName, remoteName);
logger.info("删除文件状态码:{}", result);
return true;
} catch (Exception e) {
logger.error("删除文件失败:{}", e.getMessage());
return false;
}
}
/**
* 文件下载
* @param remoteFileName 文件存储路径 参数格式 group1/M00/00/CF/*.png
*/
public static byte[] downloadFile(String remoteFileName) {
try {
if (StringUtil.isEmpty(remoteFileName)){
logger.info("文件下载远程地址不能为空:{}", remoteFileName);
return null;
}
// 提取 groupName 和 remoteName
String groupName = remoteFileName.substring(0, GROUP_NAME_LENGTH);
String remoteName = remoteFileName.substring(REMOTE_NAME_START_INDEX);
// 调用 download_file 方法
byte[] bytes = storageClient.download_file(groupName, remoteName);
if (bytes == null) {
logger.error("下载文件错误,错误码: " + storageClient.getErrorCode());
return null;
}
// 复制原始字节数组,防止改变原文件
return bytes.clone();
} catch (Exception e) {
e.printStackTrace();
logger.error("下载文件失败:{}", e.getMessage());
}
return null;
}
}
使用
/**
* 文件上传
* @param file 文件
*/
@ResponseBody
@RequestMapping("/uploadFile")
public R<String> uploadFile(@RequestParam("file") MultipartFile file) {
try {
// 文件内容
byte[] bytes = file.getBytes();
String fileName = file.getOriginalFilename();
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
logger.info("上传文件名:{},文件格式:{}", fileName, fileType);
String fileUrl = FastDFSUtils.upload(bytes , fileType);
logger.info("上传后文件地址:{}", fileUrl);
return R.ok(fileUrl);
}catch (Exception e){
logger.error("上传失败:{}", e.getMessage());
return R.fail("上传失败" + e.getMessage());
}
}
最后
至此Fastdfs使用就结束了,后续扩展则需要根据相应的需求进行调整即可,文件上传、文件下载、文件删除三个接口都已实现,只需要把远程路径当作参数即可