分布式文件系统 SpringBoot+FastDFS+Vue.js【四】

分布式文件系统 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.效果

分布式文件系统 SpringBoot+FastDFS+Vue.js【四】_第1张图片
分布式文件系统 SpringBoot+FastDFS+Vue.js【四】_第2张图片
分布式文件系统 SpringBoot+FastDFS+Vue.js【四】_第3张图片
分布式文件系统 SpringBoot+FastDFS+Vue.js【四】_第4张图片

九、总结

  • 案例有些不足
  • 功能太简单
  • 功能复杂可以做一个类似网盘的文件管理系统
  • 仅仅学习使用某些功能
  • 暂不深入开发
  • 有兴趣的伙伴可以尝试一番
  • 类似于阿里云oss

endl

你可能感兴趣的:(vue,springboot,spring,boot,vue.js,后端)