客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。
提示:没有安装Docker的可以参考文章
Docker入门(一)
docker pull morunchang/fastdfs
docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh
提示:TRACKER_IP务必换成自己的服务器ip
docker run -d --name storage --net=host -e TRACKER_IP=服务器IP:22122 -e GROUP_NAME=group1 morunchang/fastdfs sh storage.sh
docker exec -it storage /bin/bash
vi /etc/nginx/conf/nginx.conf
向nginx.conf配置文件中加入,如果已存在,请略过这一步
location ~ /M00 {
//数据存储路径
root /data/fast_data/data;
ngx_fastdfs_module;
//禁止缓存
add_header Cache-Control no-store;
}
修改保存完后退出并重启storage容器
提示:不了解配置文件请跳过
再次进入storage容器
docker exec -it storage /bin/bash
进入配置文件目录
cd /etc/fdfs
<dependency>
<groupId>com.github.tobatogroupId>
<artifactId>fastdfs-clientartifactId>
<version>1.26.7version>
dependency>
fdfs:
# 链接超时
connect-timeout: 60
# 读取时间
so-timeout: 60
# 生成缩略图参数
thumb-image:
width: 150
height: 150
tracker-list: 服务器IP:22122
@Resource
private FastFileStorageClient storageClient;
public String upload(MultipartFile multipartFile) throws Exception {
String originalFilename = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1);
StorePath storePath = this.storageClient.uploadImageAndCrtThumbImage(multipartFile.getInputStream(),multipartFile.getSize(), originalFilename, null);
return storePath.getFullPath();
}
@Resource
private FastFileStorageClient storageClient;
public void deleteFile(String fileUrl) {
if (StringUtils.isEmpty(fileUrl)) {
LOGGER.info("fileUrl == >>文件路径为空...");
return;
}
try {
//对根据传入的url删除文件
StorePath storePath = StorePath.parseFromUrl(fileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
//删除上传所产生的缩略图
val split = fileUrl.split("\\.");
split[0] += "_150x150.";
String fileUrl2 = split[0] + split[1];
StorePath storePath2 = StorePath.parseFromUrl(fileUrl2);
storageClient.deleteFile(storePath2.getGroup(), storePath2.getPath());
} catch (Exception e) {
LOGGER.info(e.getMessage());
}
}
@Resource
private FastFileStorageClient storageClient;
public byte[] download(String fileUrl) {
String group = fileUrl.substring(0, fileUrl.indexOf("/"));
String path = fileUrl.substring(fileUrl.indexOf("/") + 1);
byte[] bytes = storageClient.downloadFile(group, path, new DownloadByteArray());
return bytes;
}
//headers必须是form-data否则无法上传文件
@RequestMapping(value = "/uploadFile", headers = "content-type=multipart/form-data", method = RequestMethod.POST)
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
String result;
try {
String path = fdfsUtil.upload(file);
if (!StringUtils.isEmpty(path)) {
result = path;
} else {
result = "上传失败";
}
} catch (Exception e) {
e.printStackTrace();
result = "服务异常";
}
return ResponseEntity.ok(result);
}
@RequestMapping(value = "/deleteByPath", method = RequestMethod.GET)
public ResponseEntity<String> deleteByPath(String filePathName) {
// String filePathName = "group1/M00/00/00/wKhjZF3WEDmAPSglAABSZAhj0eU111.jpg" ;
fdfsUtil.deleteFile(filePathName);
return ResponseEntity.ok("SUCCESS");
}
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void download(String fileUrl, HttpServletResponse response, HttpServletRequest request) throws Exception {
byte[] data = fdfsUtil.download(fileUrl);
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("下载文件名.jpg", "UTF-8"));
// 写出
ServletOutputStream outputStream = response.getOutputStream();
IOUtils.write(data, outputStream);
}
我们进入容器,进入数据储存路径/data/fast_data/data,根除返回url中的两级目录可以看到刚刚上传的图片
删除成功后再次访问文件夹,就可以看到文件已经删除
http://127.0.0.1:9004/download?fileUrl=group1/M00/00/00/wKjcgWJfKZCAdnKnAAFyuc8FC0I654.jpg
当我们访问/download?fileUrl=xxx,就会指定发起下载