【Java】根据条件筛选出服务器上指定文件(以日志文件为例)打包成压缩包(以tar.gz为例)导出到客户端

前言

需求:批量导出服务器端的log日志文件,筛选条件为日期和日志级别。(服务器端log日期存放在指定的目录,日志文件命名规则:log_${level}_${yyyy-MM-dd}_${numer}.log,其中level是日志级别,yyyy-MM-dd的日志打印日期,number是切分日志文件的计数单位),要求根据传入的日期和日志级别的参数值,对应筛选出相应的日志文件,打包为压缩文件导出。

本此实例中以打 .tar.gz 压缩包为例,分为不筛选打包和添加筛选条件打包两种情况。

依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.21</version>
</dependency>

不添加筛选条件

    /**
     * 把一个目录下的所有文件和文件夹打成.tar.gz包(从当前的目录开始)
     * <p>Method :createTarFile
     * <p>Description : 打包文件 .tar.gz
     *
     * @param sourceFolder  需要打成.tar.gz包的目录(包含目录和目录下的所有文件和文件夹)例:E:/aarm/test
     * @param tarGzPath     打成的tar包生成的目标目录 例: D:/tmp  最终打包会在 D:/tmp目录下生成 test.tar.gz包
     * @param ignoreDir     需要忽略的目录
     * @param tarGzFileName 打tar.gz包的名,例如:ide-sdk.tar.gz
     */
    public static void createTarFile(String sourceFolder, String tarGzPath, String ignoreDir, String tarGzFileName) {
        TarArchiveOutputStream tarOs = null;
        try {
            File tarGzFile = new File(tarGzPath);
            if (!tarGzFile.exists()) {
                tarGzFile.mkdirs();
            }

            File sourceFile = new File(sourceFolder);
            if (!sourceFile.exists()) {
                throw new FileNotFoundException("压缩的目录不存在。。。");
            }
            // 创建一个 FileOutputStream 到输出文件(.tar.gz)
            File tarFile = new File(tarGzFile + "/" + tarGzFileName);
            FileOutputStream fos = new FileOutputStream(tarFile);
//			// 创建一个 GZIPOutputStream,用来包装 FileOutputStream 对象
            GZIPOutputStream gos = new GZIPOutputStream(new BufferedOutputStream(fos));
            // 创建一个 TarArchiveOutputStream,用来包装 GZIPOutputStream 对象
            tarOs = new TarArchiveOutputStream(gos);
            // 若不设置此模式,当文件名超过 100 个字节时会抛出异常,异常大致如下:
            // is too long ( > 100 bytes)
            // 具体可参考官方文档:http://commons.apache.org/proper/commons-compress/tar.html#Long_File_Names
            tarOs.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
            addFilesToTarGZ(sourceFile, "", tarOs, ignoreDir);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                tarOs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 把文件复制到.tar.gz包中  不过滤 目录下所有文件全部打包下载
     *
     * @param file       需要复制的文件或目录
     * @param parent     父目录
     * @param tarArchive tar包流
     * @param ignoreDir  忽略的目录
     * @throws IOException 异常
     */
    public static void addFilesToTarGZ(File file, String parent, TarArchiveOutputStream tarArchive, String ignoreDir)
            throws IOException {
        //不要再包一层最上面的目录
        if (parent.startsWith(ignoreDir + File.separator)) {
            parent = parent.replace(ignoreDir + File.separator, File.separator);
        }
        String entryName = parent + file.getName();
        // System.out.println("file.getName()------:" + file.getName());
        if (!parent.equals("")) {
            // 添加 tar ArchiveEntry
            tarArchive.putArchiveEntry(new TarArchiveEntry(file, entryName));
        }
        if (file.isFile()) {
            // 根据文件默判断过滤,将符合条件的日志文件写入到压缩文件中
            String fileName = file.getName();
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            // 写入文件
            IOUtils.copy(bis, tarArchive);
            tarArchive.closeArchiveEntry();
            bis.close();

        } else if (file.isDirectory()) {
            // 因为是个文件夹,无需写入内容,关闭即可
            if (!parent.equals("")) {
                tarArchive.closeArchiveEntry();
            }
            File[] files = file.listFiles();
            if (files != null) {
                // 读取文件夹下所有文件
                for (File f : files) {
                    // 递归
                    addFilesToTarGZ(new File(f.getAbsolutePath()), entryName + File.separator, tarArchive, ignoreDir);
                }
            }
        }
    }

添加筛选条件


    /**
     * 把一个目录下的所有文件和文件夹打成.tar.gz包(从当前的目录开始)
     * <p>Method :createTarFile
     * <p>Description : 打包文件 .tar.gz
     *
     * @param sourceFolder  需要打成.tar.gz包的目录(包含目录和目录下的所有文件和文件夹)例:E:/aarm/test
     * @param tarGzPath     打成的tar包生成的目标目录 例: D:/tmp  最终打包会在 D:/tmp目录下生成 test.tar.gz包
     * @param ignoreDir     需要忽略的目录
     * @param tarGzFileName 打tar.gz包的名,例如:ide-sdk.tar.gz
     */
    public static void createTarFile(String sourceFolder, String tarGzPath, String ignoreDir, String tarGzFileName, String logLevel, String date) {
        TarArchiveOutputStream tarOs = null;
        try {
            File tarGzFile = new File(tarGzPath);
            if (!tarGzFile.exists()) {
                tarGzFile.mkdirs();
            }

            File sourceFile = new File(sourceFolder);
            if (!sourceFile.exists()) {
                throw new FileNotFoundException("压缩的目录不存在。。。");
            }
            // 创建一个 FileOutputStream 到输出文件(.tar.gz)
            File tarFile = new File(tarGzFile + "/" + tarGzFileName);
            FileOutputStream fos = new FileOutputStream(tarFile);
//			// 创建一个 GZIPOutputStream,用来包装 FileOutputStream 对象
            GZIPOutputStream gos = new GZIPOutputStream(new BufferedOutputStream(fos));
            // 创建一个 TarArchiveOutputStream,用来包装 GZIPOutputStream 对象
            tarOs = new TarArchiveOutputStream(gos);
            // 若不设置此模式,当文件名超过 100 个字节时会抛出异常,异常大致如下:
            // is too long ( > 100 bytes)
            // 具体可参考官方文档:http://commons.apache.org/proper/commons-compress/tar.html#Long_File_Names
            tarOs.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
            addFilesToTarGZ2(sourceFile, "", tarOs, ignoreDir, logLevel, date);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                tarOs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 把文件复制到.tar.gz包中 打包前添加 日期 日志级别的 过滤条件,至打包符合条件的
     *
     * @param file       需要复制的文件或目录
     * @param parent     父目录
     * @param tarArchive tar包流
     * @param ignoreDir  忽略的目录
     * @throws IOException 异常
     */
    public static void addFilesToTarGZ2(File file, String parent, TarArchiveOutputStream tarArchive, String ignoreDir, String logLevel, String date)
            throws IOException {
        //不要再包一层最上面的目录
        if (parent.startsWith(ignoreDir + File.separator)) {
            parent = parent.replace(ignoreDir + File.separator, File.separator);
        }
        String entryName = parent + file.getName();
        System.out.println("file.getName()--date-parent---:" + parent);
        System.out.println("file.getName()--date-file---:" + file.getName());

        if (file.isFile()) {
            // 根据文件默判断过滤,将符合条件的日志文件写入到压缩文件中
            String fileName = file.getName();
            // 先筛选符合日期的
            if (Strings.isNotBlank(date) && fileName.contains(date)) {
                System.out.println("file.getName()--date-file---:" + fileName);
                // 再筛选符合日志级别的
                boolean infoOrError = (LogLevel.INFO.getValue().equals(logLevel)
                        || LogLevel.ERROR.getValue().equals(logLevel)) && fileName.contains(logLevel);
                boolean infoAndError = LogLevel.ALL.getValue().equals(logLevel);
                if (infoOrError || infoAndError) {
                    if (!parent.equals("")) {
                        // 添加 tar ArchiveEntry
                        tarArchive.putArchiveEntry(new TarArchiveEntry(file, entryName));
                    }

                    FileInputStream fis = new FileInputStream(file);
                    BufferedInputStream bis = new BufferedInputStream(fis);
                    // 写入文件
                    IOUtils.copy(bis, tarArchive);
                    tarArchive.closeArchiveEntry();
                    bis.close();
                }
            }

        } else if (file.isDirectory()) {
            // 因为是个文件夹,无需写入内容,关闭即可
            /*if (!parent.equals("")) {
                tarArchive.closeArchiveEntry();
            }*/
            File[] files = file.listFiles();
            if (files != null) {
                // 读取文件夹下所有文件
                for (File f : files) {
                    // 递归
                    addFilesToTarGZ2(new File(f.getAbsolutePath()), entryName + File.separator, tarArchive, ignoreDir, logLevel, date);
                }
            }
        }
    }


方法中用于判断的自定义枚举类

    public enum LogLevel {
        ALL("all"), INFO("info"), ERROR("error");
        String value;

        LogLevel(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }
    }

测试demo

    public static void main(String[] args) {
        String sourceFilePath = "D:\\logs";
        String tarFilePath = "D:\\test";
        String tarFileName = "demo.tar.gz";
        String date = "2022-08-31";
        String logLevel = "error";
        createTarFile(sourceFilePath, tarFilePath, "", tarFileName, logLevel, date);
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值