分布式文件系统 SpringBoot+FastDFS+Vue.js【四】
- 八、文件的下载和删除功能
- 8.1.FastDFSClient.java
- 8.2.FileServerController.java
- 8.3.Vue的fast.js
- 8.4.fastdfsimg.vue
- 8.5.效果
- 九、总结
- endl
八、文件的下载和删除功能
8.1.FastDFSClient.java
@Slf4j
public class FastDFSClient {
static {
//加载fastDFS客户端的配置文件
try {
ClientGlobal.initByProperties("config/fastdfs-client.properties");
log.info("network_timeout = {} ms", ClientGlobal.g_network_timeout);
log.info("charset= {}", ClientGlobal.g_charset);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
/**
* 上传文件
*
* @param file
* @param fastDFSFile
* @return
* @throws IOException
*/
public static FastDfsFile upload(MultipartFile file, FastDfsFile fastDFSFile) throws IOException {
byte[] file_buff = null;
//把文件转成输入流
InputStream inputStream = file.getInputStream();
if (inputStream != null) {
//获取输入流中可读取的数据大小
int len = inputStream.available();
//创建足够大的缓冲区
file_buff = new byte[len];
//一次性把输入流中的数据全都读入到缓冲区file_buff,那file_buff就要足够大,占用内存也会很大
inputStream.read(file_buff);
}
//关闭输入流
inputStream.close();
//通过fastDSF的client代码访问tracker和storage
try {
//创建tracker的客户端
TrackerClient trackerClient = new TrackerClient(ClientGlobal.getG_tracker_group());
//通过TrackerClient对象获取TrackerServer信息
TrackerServer trackerServer = trackerClient.getTrackerServer();
StorageServer storageServer = null;
//定义storage的客户端,建立与Storage服务器的连接
StorageClient1 storageClient = new StorageClient1(trackerServer, storageServer);
//文件元信息
NameValuePair[] metaList = new NameValuePair[1];
metaList[0] = new NameValuePair("fileName", fastDFSFile.getFileName());
//执行上传
String fileId = storageClient.upload_file1(file_buff, fastDFSFile.getExt(), metaList);
log.info("upload success. file id is: {}", fileId);
fastDFSFile.setFileId(fileId);
fastDFSFile.setFilePath(fileId);
fastDFSFile.setFileSize(file.getSize());
fastDFSFile.setCreateTime(LocalDateTime.now());
fastDFSFile.setUpdateTime(LocalDateTime.now());
//通过调用service及dao将文件的路径存储到数据库中
//关闭storage客户端
storageClient.close();
return fastDFSFile;
} catch (Exception e) {
log.error("上传文件失败:", e);
e.printStackTrace();
return null;
}
}
/**
* 删除文件
*
* @param file_id
* @return
* @throws IOException
* @throws MyException
*/
public static Boolean delete(String file_id) throws IOException, MyException {
//通过fastDSF的client代码访问tracker和storage
//创建tracker的客户端
TrackerClient trackerClient = new TrackerClient(ClientGlobal.getG_tracker_group());
//通过TrackerClient对象获取TrackerServer信息
TrackerServer trackerServer = trackerClient.getTrackerServer();
StorageServer storageServer = null;
//定义storage的客户端,建立与Storage服务器的连接
StorageClient1 storageClient = new StorageClient1(trackerServer, storageServer);
//查询文件
//upload success. file id is: group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png
String[] splitStr = file_id.split("/");
String group_name = splitStr[0];//group1
String remoteFileName = "";//M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png
for (int i = 1; i < splitStr.length; i++) {
remoteFileName += splitStr[i];
if (i != splitStr.length - 1) {
remoteFileName += "/";
}
}
log.info("group_name : {}", group_name);
log.info("remoteFileName : {}", remoteFileName);
FileInfo fileInfo = storageClient.query_file_info(group_name, remoteFileName);
log.info("fileInfo = {}", fileInfo);
if (fileInfo == null) {
log.info("您删除的文件信息不存在,请核对后再次删除......");
return false;
}
storageClient.delete_file1(file_id);
log.info("删除成功");
//关闭storage客户端
storageClient.close();
return true;
}
/**
* 下载文件
*
* @param file_id
* @throws IOException
* @throws MyException
*/
public static byte[] downloadFastFile(String file_id) throws IOException, MyException {
//通过fastDSF的client代码访问tracker和storage
//创建tracker的客户端
TrackerClient trackerClient = new TrackerClient(ClientGlobal.getG_tracker_group());
//通过TrackerClient对象获取TrackerServer信息
TrackerServer trackerServer = trackerClient.getTrackerServer();
StorageServer storageServer = null;
//定义storage的客户端,建立与Storage服务器的连接
StorageClient1 storageClient = new StorageClient1(trackerServer, storageServer);
//查询文件
//upload success. file id is: group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png
String[] splitStr = file_id.split("/");
String group_name = splitStr[0];//group1
String remoteFileName = "";//M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png
for (int i = 1; i < splitStr.length; i++) {
remoteFileName += splitStr[i];
if (i != splitStr.length - 1) {
remoteFileName += "/";
}
}
log.info("group_name : {}", group_name);
log.info("remoteFileName : {}", remoteFileName);
FileInfo fileInfo = storageClient.query_file_info(group_name, remoteFileName);
log.info("fileInfo = {}", fileInfo);
if (fileInfo == null) {
log.info("您下载的文件信息不存在,请核对后再次下载......");
return null;
}
//下载操作,传文件id返回字节流
byte[] bytes = storageClient.download_file1(file_id);
//关闭storage客户端
storageClient.close();
return bytes;
}
}
8.2.FileServerController.java
@Slf4j
@RestController
@RequestMapping("/fastDFSFile")
public class FileServerController {
@Resource
private FastDfsFileService fastDfsFileService;
@Resource
private FastDfsFileTypeService fastDfsFileTypeService;
@PostMapping("/upload")
@ResponseBody
public R upload(@RequestParam("file") MultipartFile file) throws IOException {
//将文件先存储在web服务器上(本机),在调用fastDFS的client将文件上传到 fastDFS服务器
FastDfsFile fastDFSFile = new FastDfsFile();
String contentType = file.getContentType();
//检验当前文件是否在上述集合中
log.info("上传的文件类型为:{}", contentType);
int count = fastDfsFileTypeService.selectByFileType(contentType);
if (count < 1) {
log.info("不支持此文件类型上传 : {}", contentType);
return R.error().setCode(208).setMessage("不支持此文件类型上传 : " + contentType);
}
log.info("此文件类型为 : {}", contentType);
fastDFSFile.setFileType(contentType);
//文件原始名称
String originalFilename = file.getOriginalFilename();
log.info("原始文件名称 : {}", originalFilename);
fastDFSFile.setFileName(originalFilename);
//文件扩展名比如22.jpg
String filenameExtension = StringUtils.getFilenameExtension(originalFilename);
log.info("文件类型 = {}", filenameExtension);//jpg
if (filenameExtension == null) {
return R.error().setCode(208).setMessage("此文件没有文件扩展名");
}
fastDFSFile.setExt(filenameExtension);
//新文件名称
String fileName = UUID.randomUUID().toString().replace("-", "") + "." + filenameExtension;
log.info("新文件名称 = {}", fileName);
FastDfsFile fastDfsFile1 = FastDFSClient.upload(file, fastDFSFile);
if (fastDfsFile1 != null) {
fastDfsFileService.save(fastDfsFile1);
Long id = fastDfsFileService.selectByFileId(fastDfsFile1.getFileId());
fastDfsFile1.setId(id);
return R.ok().setCode(200).setMessage("上传成功").data("fastDfsFile", fastDfsFile1);
}
return R.error().setCode(208).setMessage("上传失败");
}
//restful风格
@DeleteMapping()
public R delete(@RequestParam("id") Long id, @RequestParam("fileId") String fileId) throws MyException, IOException {
Boolean result = FastDFSClient.delete(fileId);
if (!result) {
log.info("删除失败");
return R.error().setCode(208).setMessage("删除失败");
}
int count = fastDfsFileService.deleteFastDfsFileById(id);
if (count < 1) {
log.info("删除失败");
return R.error().setCode(208).setMessage("删除失败");
}
log.info("删除成功");
return R.ok().setCode(200).setMessage("删除成功");
}
@GetMapping()
public void downloadfile(HttpServletResponse response, String fileId, String fileName) throws IOException, MyException {
if (fileId == null) return;
log.info("fileName = {}", fileName);
response.setContentType("application/force-download;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes("gb2312"), "ISO-8859-1"));
byte[] bytes = FastDFSClient.downloadFastFile(fileId);
FileInputStream fis = null;
log.info("fileId = {}", fileId);
int len = 0;
OutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
if (bytes == null) {
return;
}
log.info("success");
outputStream.write(bytes);
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
if (fis != null) {
fis.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@GetMapping("/getPageFastImg/{page}/{limit}")
public R getPageFastImg(@PathVariable int page, @PathVariable int limit) {
PageBean<FastDfsFile> pageBean = fastDfsFileService.findFastDfsFileByPage(page, limit);
return R.ok().setCode(200).setMessage("查询成功").data("pageBean", pageBean);
}
}
8.3.Vue的fast.js
import request from "../../utils/request";
const api_name = '/fastDFSFile'
export default {
//上传图片
uploadImg() {
return request({
url: `${api_name}`,
method: 'post',
})
},
getPageFastImg(page, limit) {
return request({
url: `${api_name}/getPageFastImg/${page}/${limit}`,
method: 'get',
})
},
getNextPageFastImg(page, limit) {
return request({
url: `${api_name}/getPageFastImg/${page}/${limit}`,
method: 'get',
})
},
//restful风格 ?id=123&fileId=456
deleteFastImg(id, fileId) {
return request({
url: `${api_name}`,
method: 'delete',
params: {
"id": id,
"fileId": fileId
}
})
},
getFileSrc(fileId) {
return request({
url: `${api_name}`,
method: 'get',
params: {
"fileId": fileId
},
responseType: 'blod'
})
},
}
8.4.fastdfsimg.vue
<template>
<div>
<h2>图片管理</h2>
<!--图片列表-->
<el-table
size="small"
style="margin: 30px;"
empty-text="无数据"
:data="imgList"
highlight-current-row v-loading="loading" border element-loading-text="拼命加载中">
<el-table-column align="center" sortable prop="filePath" label="文件路径" width="450"></el-table-column>
<el-table-column align="center" sortable prop="fileSize" label="文件大小" width="100"></el-table-column>
<el-table-column align="center" sortable prop="fileName" label="文件名" width="130"></el-table-column>
<el-table-column align="center" sortable prop="ext" label="扩展名" width="100"></el-table-column>
<el-table-column align="center" sortable prop="fileType" label="文件类型" width="100"></el-table-column>
<el-table-column align="center" sortable prop="filePath" label="预览图片" width="100">
<template slot-scope="scope">
<img :src="getImageUrl(scope.row.filePath)" style="max-width: 100px;max-height: 100px" alt="图标"/>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" icon="el-icon-download" @click="getFileSrc(scope.row)">下载</el-button>
<el-popconfirm title="确定删除吗?" @confirm="handleDeleteOne(scope.row)">
<template #reference>
<el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination class="pagination" style="text-align: center;margin-top: 50px"
layout="prev, pager, next"
:current-page="page"
:total="total"
:page-size="limit"
@current-change="fetchData">
</el-pagination>
</div>
</template>
<script>
import fastApi from "@/api/fastdfs/fast";
import request from "../../utils/request";
export default {
name: "FastdfsImg",
data() {
return {
total: 0, // 数据库中的总记录数
page: 1, // 默认页码
limit: 5, // 每页记录数
imgList: {},
//imagePath: 'http://192.168.229.141/', // 图片的基础路径
}
},
created() {
this.init()
},
methods: {
init() {
fastApi.getPageFastImg(this.page, this.limit).then(response => {
this.imgList = response.data.pageBean.lists
this.total = response.data.pageBean.totalCount
})
},
//获取图片路径
getImageUrl(filePath) {
//return `${this.imagePath}${filePath}`; // 拼接图片路径
return this.$baseImagePath + '/' + filePath; // 拼接图片路径
},
//下一页
fetchData(page) {
this.page = page
fastApi.getNextPageFastImg(this.page, this.limit).then(response => {
this.imgList = response.data.pageBean.lists
this.total = response.data.pageBean.totalCount
})
},
// 单选删除
handleDeleteOne(FastDfsFile) {
fastApi.deleteFastImg(FastDfsFile.id, FastDfsFile.fileId).then(response => {
this.$message.success(response.message)
this.init()
})
},
// 下载文件
getFileSrc(FastDfsFile) {
//window.open(this.$baseImagePath+'/'+FastDfsFile.fileId,"_blank");
/*fastApi.downloadFastImg(FastDfsFile.fileId).then(response=>{
this.$message.success(response.message)
})*/
window.location.href = request.defaults.baseURL + '/fastDFSFile?fileId=' + FastDfsFile.fileId + '&&fileName=' + FastDfsFile.fileName;
}
},
}
</script>
<style scoped>
</style>
8.5.效果
九、总结
- 案例有些不足
- 功能太简单
- 功能复杂可以做一个类似网盘的文件管理系统
- 仅仅学习使用某些功能
- 暂不深入开发
- 有兴趣的伙伴可以尝试一番
- 类似于阿里云oss