文件工具类

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.zip.*;

public class FileUtils {

    private static Logger logger = LoggerFactory.getLogger(FileUtils.class);

    /**
     * 断点续传,下载文件
     * @param file 文件实体
     * @param fileName 文件名
     * @param req 请求
     * @param res 响应
     */
    public static void download(File file, String fileName, HttpServletRequest req, HttpServletResponse res) throws UnsupportedEncodingException {

        // 添加缓存头
        long modificationDate = file.lastModified();
        res.setHeader("Last-Modified", modificationDate + "");
        // 缓存3个月
        res.setHeader("cache-control", "max-age=7776000");

        // get MIME type of the file
        String mimeType = "application/octet-stream";

        // set content attributes for the response
        res.setContentType(mimeType);
        // response.setContentLength((int) downloadFile.length());

        // set headers for the response
        String headerKey = "Content-Disposition";
        String fileDateName = "";
        if(fileName.indexOf(".") > -1){
            fileDateName = fileName.substring(0, fileName.lastIndexOf(".")) + "_" +
                            System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf("."));
        } else {
            fileDateName = fileName;
        }
        String headerValue = String.format("attachment; filename=\"%s\"", new String(fileName.getBytes(),"iso-8859-1"));
        res.setHeader(headerKey, headerValue);
        // 解析断点续传相关信息
        res.setHeader("Accept-Ranges", "bytes");
        long downloadSize = file.length();
        long fromPos = 0, toPos = 0;
        if (req.getHeader("Range") == null) {
            res.setHeader("Content-Length", downloadSize + "");
        } else {
            // 若客户端传来Range,说明之前下载了一部分,设置206状态(SC_PARTIAL_CONTENT)
            res.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            String range = req.getHeader("Range");
            String bytes = range.replaceAll("bytes=", "");
            String[] ary = bytes.split("-");
            fromPos = Long.parseLong(ary[0]);
            if (ary.length == 2) {
                toPos = Long.parseLong(ary[1]);
            }
            int size;
            if (toPos > fromPos) {
                size = (int) (toPos - fromPos);
            } else {
                size = (int) (downloadSize - fromPos);
            }
            res.setHeader("Content-Length", size + "");
            downloadSize = size;
        }
        // Copy the stream to the response's output stream.
        RandomAccessFile in = null;
        OutputStream out = null;
        try {
            in = new RandomAccessFile(file, "rw");
            // 设置下载起始位置
            if (fromPos > 0) {
                in.seek(fromPos);
            }
            // 缓冲区大小
            int bufLen = (int) (downloadSize < 2048 ? downloadSize : 2048);
            byte[] buffer = new byte[bufLen];
            int num;
            int count = 0; // 当前写到客户端的大小
            out = res.getOutputStream();
            while ((num = in.read(buffer)) > 0) {
                out.write(buffer, 0, num);
                count += num;
                //处理最后一段,计算不满缓冲区的大小
                if (downloadSize - count < bufLen) {
                    bufLen = (int) (downloadSize-count);
                    if(bufLen==0){
                        break;
                    }
                    buffer = new byte[bufLen];
                }
            }
            res.flushBuffer();
        } catch (IOException e) {
            logger.error("-->下载文件出错 error msg : {}", e.getMessage());
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    logger.error("-->下载文件出错 out.close error msg : {}", e.getMessage());
                }
            }
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    logger.error("-->下载文件出错 in.close error msg : {}", e.getMessage());
                }
            }
        }
    }

    public static void downloadVideo(File file, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {
            fis = new FileInputStream(file);
            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            byte[] buffer = bos.toByteArray();
            response.setContentType("application/octet-stream");
            response.setHeader("Accept-Ranges", "bytes");
            response.setContentLength(buffer.length);
            response.getOutputStream().write(buffer);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }

    public static String getFileMd5(String filePath) throws IOException {
        FileInputStream fileInputStream;
        try {
            fileInputStream = new FileInputStream(filePath);
            String md5 = DigestUtils.md5Hex(fileInputStream);
            fileInputStream.close();
            return md5;
        } catch (Exception e) {
            logger.error("get file md5 error, path: {}", filePath, e);
            return null;
        }
    }


    public static boolean existFile(String filePath) {
        File file;
        try {
            file = new File(filePath);
        } catch (Exception e) {
            return false;
        }
        return file.exists();
    }


    /**
     * @Description:
     *     压缩文件,支持将多个文件或目录压缩到同一个压缩文件中
     * @param zipEntries 压缩源
     * @param zipPath 生成压缩文件的路径,请使用绝对路径。该路不能为空,并且必须以“.zip”为结尾
     * @param comment 压缩注释
     */
    public static String zip(List<ThsZipEntry> zipEntries, String zipPath, String comment)
        throws IOException {
        // 设置压缩文件路径,默认为将要压缩的路径的父目录为压缩文件的父目录
        if (zipPath == null || "".equals(zipPath) || !zipPath.endsWith(".zip")) {
            throw new FileNotFoundException("必须指定一个压缩路径,而且该路径必须以'.zip'为结尾");
        }
        // 要创建的压缩文件的父目录不存在,则创建
        File zipFile = new File(zipPath);
        if (!zipFile.getParentFile().exists()) {
            zipFile.getParentFile().mkdirs();
        }
        // 创建压缩文件输出流
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(zipPath);
        } catch (FileNotFoundException e) {
            if (fos != null) {
                try{ fos.close(); } catch (Exception e1) {}
            }
        }
        // 使用指定校验和创建输出流
        CheckedOutputStream csum = new CheckedOutputStream(fos, new CRC32());
        // 创建压缩流
        ZipOutputStream zos = new ZipOutputStream(csum);
        // 设置压缩包注释
        zos.setComment(comment);
        // 启用压缩
        zos.setMethod(ZipOutputStream.DEFLATED);
        // 设置压缩级别为最强压缩
        zos.setLevel(Deflater.BEST_COMPRESSION);
        // 压缩文件缓冲流
        BufferedOutputStream bout = null;
        try {
            // 封装压缩流为缓冲流
            bout = new BufferedOutputStream(zos);
            for (ThsZipEntry entry : zipEntries) {
                // 读取将要压缩的文件的输入流
                BufferedInputStream bin = null;
                try{
                    File file = new File(entry.getEntryValue());
                    if (!file.exists()) {
                        continue;
                    }
                    if (file.isDirectory()) {
                        for (File child : file.listFiles()) {
                            String topPath = entry.getEntryValue().replaceAll("\\\\", "/");
                            addZipFileEntry(entry.getEntryName(), topPath, child, zos, bout);
                        }
                    } else {
                        // 开始写入新的ZIP文件条目并将流定位到条目数据的开始处
                        ZipEntry zipEntry = new ZipEntry(entry.getEntryName());
                        // 向压缩流中写入一个新的条目
                        zos.putNextEntry(zipEntry);
                        // 获取输入流读取文件
                        bin = new BufferedInputStream(new FileInputStream(entry.getEntryValue()));
                        // 读取文件,并写入压缩流
                        byte[] buffer = new byte[1024];
                        int readCount = -1;
                        while ((readCount = bin.read(buffer)) != -1) {
                            bout.write(buffer, 0, readCount);
                        }

                    }
                    // 注,在使用缓冲流写压缩文件时,一个条件完后一定要刷新,不然可能有的内容就会存入到后面条目中去了
                    bout.flush();
                    // 关闭当前ZIP条目并定位流以写入下一个条目
                    zos.closeEntry();
                } catch (Exception e) {

                } finally {
                    if (bin != null) {
                        try { bin.close(); } catch (IOException e) {}
                    }
                }
            }
        } finally {
            if (bout != null) {
                try{ bout.close(); } catch (Exception e) {}
            }
        }
        return zipPath;
    }


    private static void addZipFileEntry(String topEntry, String topPath, File entryFile, ZipOutputStream zos, BufferedOutputStream bout) {
        BufferedInputStream bin = null;
        try {
            if (entryFile == null || !entryFile.exists()) {
                return;
            }
            if (entryFile.isDirectory()) {
                for (File child : entryFile.listFiles()) {
                    addZipFileEntry(topEntry, topPath, child, zos, bout);
                }
            } else {
                String fileEntryName = entryFile.getAbsolutePath().replaceAll("\\\\", "/").replace(topPath, "");
                String fileFullEntryName = topEntry + fileEntryName;
                // 开始写入新的ZIP文件条目并将流定位到条目数据的开始处
                ZipEntry zipEntry = new ZipEntry(fileFullEntryName);
                // 向压缩流中写入一个新的条目
                zos.putNextEntry(zipEntry);
                // 读取将要压缩的文件的输入流
                // 获取输入流读取文件
                bin = new BufferedInputStream(new FileInputStream(entryFile));
                // 读取文件,并写入压缩流
                byte[] buffer = new byte[1024];
                int readCount = -1;
                while ((readCount = bin.read(buffer)) != -1) {
                    bout.write(buffer, 0, readCount);
                }
            }
            // 注,在使用缓冲流写压缩文件时,一个条件完后一定要刷新,不然可能有的内容就会存入到后面条目中去了
            bout.flush();
            // 关闭当前ZIP条目并定位流以写入下一个条目
            zos.closeEntry();

        } catch (Exception e) {

        } finally {
            if (bin != null) {
                try { bin.close(); } catch (IOException e) {}
            }
        }

    }


    /**
     * 解压zip文件
     * @param sourceZipPath 源zip文件
     * @param targetPath 解压目标路径
     * @return 解压后的路径 targetPath + zipName
     */
    public static String unzip(String sourceZipPath, String targetPath) throws IOException {
        try (ZipInputStream zip = new ZipInputStream(new FileInputStream(new File(sourceZipPath)), Charset.forName("gbk"))) {
            File targetDir = new File(targetPath);
            if (!targetDir.exists()) targetDir.mkdirs();

            String zipFullName = new File(sourceZipPath).getName();
            String zipName = zipFullName.substring(0, zipFullName.lastIndexOf("."));
            ZipEntry zipEntry;
            String zipEntryName;
            File zipEntryFile;
            while ((zipEntry = zip.getNextEntry()) != null) {
                zipEntryName = zipEntry.getName();
                zipEntryFile = new File(targetDir.getAbsolutePath() + "/" + zipName + "/" + zipEntryName);
                if (zipEntryName.endsWith("/")) {
                    zipEntryFile.mkdirs();
                } else {
                    if (!zipEntryFile.getParentFile().exists()) {
                        zipEntryFile.getParentFile().mkdirs();
                    }
                    BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(zipEntryFile));
                    byte[] byte_s = new byte[1024];
                    int num;
                    while ((num = zip.read(byte_s, 0, byte_s.length)) > -1) {
                        outputStream.write(byte_s, 0, num);
                    }
                    outputStream.close();
                }
            }
            return (targetDir.getAbsolutePath() + "/" + zipName).replaceAll("\\\\", "/");
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 把输入流转为文件
     * @param ins
     * @param fileSaveDirPath
     * @param fileName
     */
    public static String saveInputStream(InputStream ins, String fileSaveDirPath, String fileName) throws IOException {
        OutputStream os = null;
        try {
            if (!fileSaveDirPath.endsWith("/")) {
                fileSaveDirPath = fileSaveDirPath + "/";
            }
            File file = new File(fileSaveDirPath + fileName);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
            return file.getAbsolutePath();
        } catch (Exception e) {
            throw e;
        } finally {
            try {
                if(os != null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(ins != null){
                    ins.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String readFile(String filePath) {
        String jsonStr = "";
        try {
            File jsonFile = new File(filePath);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8);
            int ch = 0;
            StringBuilder sb = new StringBuilder();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
    public static String readFile(InputStream inputsteam) {
        String jsonStr = "";
        try {

            Reader reader = new InputStreamReader(inputsteam, StandardCharsets.UTF_8);
            int ch = 0;
            StringBuilder sb = new StringBuilder();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
    public static boolean writeFile(String filePath, String content) {
        File file;
        FileOutputStream fos = null;
        try {
            file = new File(filePath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            if (content == null) content = "";
            fos = new FileOutputStream(file);
            byte[] bytesArray = content.getBytes(StandardCharsets.UTF_8);
            fos.write(bytesArray);
            fos.flush();
            return true;
        } catch (Exception e) {
            return false;
        } finally {
            try {
                if(fos != null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
/**
 * 压缩包entry类
 */
public class ThsZipEntry {

    /**
     * 压缩包内的层级
     */
    private String entryName;

    /**
     * 文件实际存放的路径的绝对路径
     */
    private String entryValue;

    public String getEntryName() {
        return entryName;
    }

    public void setEntryName(String entryName) {
        this.entryName = entryName;
    }

    public String getEntryValue() {
        return entryValue;
    }

    public void setEntryValue(String entryValue) {
        this.entryValue = entryValue;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值