记录一个java文件操作工具类

package com.xxx;

import cn.hutool.core.io.FileUtil;
import com.album.manager.response.ReturnT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/*
* @author hewenjun
* @date 2022/12/26
* */

@Slf4j
@Service //如果不加@Service或Component注解,那么@Value定义的属性获取不到
public class FileUtils {

    //不推荐使用,推荐调用公共方法时再传入路径,保持方法的公共性
//    @Value("${4mUploadFolder}")4m上传路径 --${qualityExceptionUploadFolder}品质异常上传路径
//    public String uploadFolder; //注意: 不能使用static 装饰,否则无法获取, 使用了uploadFolder的方法也一样,否则无法调用


    /*
    *获取jar所在路径地址 :一般用于保存用户上传的文件 以及 根据该路径下载用户上传的文件 ,
    * 不推荐使用jar包地址
    **/
    public static String getJarPath(){
        ApplicationHome home = new ApplicationHome(FileUtils.class);
        File jarFile = home.getSource();
        return jarFile.getParentFile().toString();
    }

    /*获取用户上传pdf等文件的地址*/
//    public String getFilePath(){
//        return getJarPath()+ UPLOAD_PATH;  //根据jar包所在地进行上传
        //当前方法不推荐使用,既然是公共方法,那么路径应该在调用的地方传进来,而不是在当前文件中写死,毕竟不一定所有文件都相同路径
//        return uploadFolder + File.separator; //固定某个位置上传上传  --》这样就不会出现测试环境与正式环境位置不相同,导致测试麻烦
//    }

    /*获取用户上传pdf等文件路径某个文件夹下的所有文件列表*/
    public List<UploadFile> getFilesByPath(String filePath){
        log.info("获取以下目录文件列表:" + filePath);
        File directoryPath = new File(filePath);  //获取已上传文件路径
        File[] filesList = directoryPath.listFiles(); //已上传文件路径下的文件详情列表  directoryPath.list()>>文件名列表
        if(null != filesList){
            List<UploadFile> files = new ArrayList<>();
            for(File file : filesList) {
               //因当前方法是公共方法,不应该指定路径filePath,只获取文件名file.getName(),下载时再拼接完整路径
                files.add(new UploadFile(org.apache.commons.io.FileUtils.sizeOf(file), file.getName() ));
            }
            return files;
        }

        return new ArrayList<>();
    }

    /*判断文件夹下是否有文件文件列表*/
    public boolean hasFileForPath(String path){
        File directoryPath = new File(path);  //获取已上传文件路径
        String[] files = directoryPath.list(); //已上传文件路径下的文件详情列表  directoryPath.list()>>文件名列表
        return null != files && files.length > 0;
    }

    /*上传文件*/
    public ReturnT fileUpload(MultipartFile file, String path) throws IOException {

        BufferedOutputStream out = null;
        String fileName = file.getOriginalFilename();

        //1. 传入固定路径,判断是否已存在同名
        File temp =new File(path + File.separator + fileName);
        if(temp.exists()) {
            return ReturnT.error("重复上传!");
        }

        long size = file.getSize()/1024/1024;//大小
        if(size > 10){
            return ReturnT.error("文件超出上传大小(10M)!");
        }
        String type = FileUtil.extName(fileName);//.jpg .pdf
        assert type != null;
        if(type.equalsIgnoreCase(".pdf")){
            return ReturnT.error("只能上传pdf");
        }

        try {
            MkdirsUtils.mkdirs(path);
            out = new BufferedOutputStream(new FileOutputStream(path + File.separator + fileName));
            out.write(file.getBytes());
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
            return ReturnT.error("上传异常失败!");
        }catch (Exception ex){
            return ReturnT.error(ex.getMessage());
        }finally {
            if(null != out){ //必须处理,否则想要再次删除文件得重启服务器,否则流一直开启是无法删除文件的
                out.close();
            }
        }
        log.info("在"+path+"路径下保存文件:" + fileName);
        return ReturnT.success("上传成功");
    }

    /*下载或预览
     * path:完整路径
     * fileName: 文件名
     * downOrRead = down -->下载   -------------else 预览
     */
    public void pdfStreamHandler(String path, String fileName, String downOrRead, HttpServletResponse response) {
        //PDF文件地址
        File file = new File(path + File.separator + fileName);
        if (file.exists()) {
            byte[] data;
            FileInputStream inStream=null;
            try {
                inStream = new FileInputStream(file);
                data = new byte[inStream.available()];
                if(downOrRead.equalsIgnoreCase("down")){ //如果是下载就需要设置格式,否则直接预览
                    response.reset();
                    response.setContentType("text/html;charset=utf-8");
                    //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
                    //attachment表示以附件方式下载  inline表示在线打开
                    // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
                    response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
                }

                // 循环取出流中的数据
                int len;
                while ((len = inStream.read(data)) > 0) {
                    response.getOutputStream().write(data, 0, len);
                }

            } catch (Exception e) {
                System.out.println("pdf文件处理异常:" + e);
            }finally{
                try {
                    if(inStream!=null){
                        inStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //下载通用方法 (文件详细路径例如:D://xxx//xxx.ppt, 文件名例如xxx.ppt)
    public static ResponseEntity<InputStreamResource> downppt(String path, String fileName) throws Exception {
        fileName = URLEncoder.encode(fileName, "utf-8"); // 导包时不要导错了是java.net的包,如果导入deploy的包是无法打包的,因为这是JDK自带的包不参与打包,所以找不到这个类
        return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header("Content-disposition", "attachment; filename=" + fileName)
                .body(new InputStreamResource(new FileInputStream(path)));
    }


    /* 删除文件 */
    public ReturnT delFile(String filePath) {
        try {
            File temp = new File(filePath);
            log.info("删除文件:" + filePath );
            if(temp.exists()) {
                return temp.delete()?ReturnT.success("del_success"):ReturnT.error("del_error!");
            }else{
                return ReturnT.success("文件不存在,前端可直接删除");
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件删除异常", e);
            return ReturnT.error("文件删除异常");
        }
    }

}

涉及到的实体1(文件列表实体):

@Data
public class UploadFile {

   private long size;
   private String fileName ; //因下载或上传方法是公共方法,不应该指定路径,只获取文件名,下载时再拼接完整路径

   public UploadFile(long size, String fileName) {
      this.size = size;
      this.fileName = fileName;
   }
}

涉及到的实体2(Controller统一返回结果实体):


import lombok.Data;

/**
 * @author hewenjun
 * @version 1.0
 * @date 2022/06/23 16:08
 */
@Data
public class ReturnT {
    private Integer code; //默认值时0,因为Layui取table值时返回code不是0就会报错格式不正确
    private String msg;
    private Object data;
    private Integer count;
    private Object result;

    public ReturnT(Integer code, String msg, Integer count, Object result) { //返回code,msg,分页数据总条数, 分页数据
        this.code = code;
        this.msg = msg;
        this.count = count;
        this.data = result;
    }

    public ReturnT(Integer code) {
        this.code = code;
    }
    public ReturnT(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public ReturnT(int code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static ReturnT error(){ return  new ReturnT(400); }
    public static ReturnT error(int code){ return  new ReturnT(code); }
    public static ReturnT error(String msg){
        return  new ReturnT(400, msg);
    }
    public static ReturnT error(int code, String msg){
        return  new ReturnT(code, msg, msg);
    }
    public static ReturnT error(String msg, Object data){
        return  new ReturnT(0, msg, data);
    }

    public static ReturnT success(){ return  new ReturnT(0); }
    public static ReturnT success(int code){ return  new ReturnT(code);  }
    public static ReturnT success(String msg){ return  new ReturnT(0, msg);  }
    public static ReturnT success(String msg, Object data){  return  new ReturnT(0, msg, data);  }
    public static ReturnT success(int code, String msg){  return  new ReturnT(code, msg);  }
    public static ReturnT success(Integer count, Object result){
        return  new ReturnT(0, "获取成功", count, result);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

往事不堪回首..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值