引言

最近需求中有使用到文件的下载功能,在之前的学习过程中我没有去注重过文件处理方面的学习,所以写起来还是有点吃力,将写出的工具类放出来供大家参考

实现步骤

下载文件

  1. 判断该文件是否存在
  2. 定义输入流,定义输出流(这里的输出位置是response.getOutputStream()
  3. 设置response返回的数据
  4. 输入流读取文件到内存,输出流读取内存中的数据输出
  5. 刷新输出流
  6. 关闭输入流,关闭输出流

删除文件

  1. 判断该文件是否存在
  2. 删除文件

删除目录(及目录下全部文件)

  1. 递归法进行删除,如果目录下存在文件或目录则无法直接删除
  2. 从最里面的文件开始删除

实现代码

这里我将实现代码全部封装在工具类中去进行实现。

import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;

/**
 * <p>
 * 文件工具类
 * </p>
 *
 * @author:雷子杰
 * @date:2022/9/5
 */
@Slf4j
public class FileUtil {

    //输入处理流
    static InputStream inputStream = null;
    //输出处理流
    static OutputStream outputStream = null;

    /**
     * 文件下载
     * @param filePath 文件在服务器的全路径
     * @param response response
     */
    public static void fileDownload(String filePath, HttpServletResponse response){
        long start = System.currentTimeMillis();

        File file = new File(filePath);
        //文件名,不含后缀
        String fileSimpleName = filePath.substring(filePath.lastIndexOf("\\")+1);

        if (!file.exists()){//如果文件不存在
            log.error("下载的文件不存在");
            return;
        }

        try {
            //定义处理流
            inputStream = new BufferedInputStream(new FileInputStream(file));
            outputStream = new BufferedOutputStream(response.getOutputStream());

            log.debug("设置response携带信息");
            log.debug("文件的大小:"+file.length());
            response.reset();
            // 设置在下载框默认显示的文件名
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileSimpleName, "UTF-8"));
            //写明文件大小
            response.addHeader("Content-Length", "" + file.length());
            // 指明response的返回对象是文件流
            response.setContentType("application/octet-stream");
            //response.setContentType("multipart/form-data");


            log.debug("开始读取文件流");
            //返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞
            byte[] bytes = new byte[inputStream.available()];
            //将pdf的内容写入bytes中
            inputStream.read(bytes);
            //将bytes中的内容写入
            outputStream.write(bytes);
            //刷新输出流,否则不会写出数据
            outputStream.flush();

            log.debug("======文件下载处理完成==========");

        } catch (FileNotFoundException e) {
            log.error("转换的pad文件未找到"+e.getMessage());
            return;
        } catch (IOException e) {
            log.error("文件读写异常"+e.getMessage());
            return;
        }finally {//关闭输入流、输出流
            try {
                if (inputStream != null){
                    inputStream.close();
                    log.debug("输入流关闭成功!");

                }
                if (outputStream != null){
                    outputStream.close();
                    log.debug("输出流关闭成功!");
                }

                long end = System.currentTimeMillis();
                log.debug("文件流处理时间"+(end-start));

            } catch (IOException e) {
                 log.error("关闭处理流出现异常"+e.getMessage());
                 return;
            }
        }

    }

    /**
     * 删除文件
     * @param path 需要删除文件的全路径
     * @return 是否删除成功
     */
    public static boolean fileDelete(String path){
        File file = new File(path);
        if (file.exists()){
            file.delete();
            return true;
        }else {
            return false;
        }

    }

    /**
     * 删除目录,及目录下的文件
     * @param directory 目录全路径
     */
    public static void fileDirDelete(String directory){
        File dir = new File(directory);

        if (!dir.exists()){//如果该目录不存在,则直接退出方法
            log.debug("该路径不存在:"+dir.getPath());
            return;
        }

        File[] files = dir.listFiles();

        for (File file : files) {
            if (file.isDirectory()){
                log.debug("进入目录:"+file.getPath());
                fileDirDelete(file.getPath());
            }else {
                log.debug("删除文件:"+file.getPath());
                file.delete();
            }
        }

        dir.delete();
        log.debug(dir.getPath()+"目录已经删除");
    }

}

测试

这里需要注意,controller的接口不能是get类型,必须的post类型,否则url会无法读取

我测试是使用的postman进行测试,如果成功执行,会提供下载的文件

image-20220905180603254

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐