使用Java 压缩文件打包tar.gz 包的详细教程

 更新时间:2021年05月13日 10:52:20   作者:异常编程  
本文带领大家学习如何使用Java 压缩文件打包tar.gz 包,主要通过 Apache compress 工具打包,通过示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

一、背景

最近,小哈主要在负责日志中台的开发工作, 等等,啥是日志中台?

俺只知道中台概念,这段时间的确很火,但是日志中台又是用来干啥的?

这里小哈尽量地通俗的说下日志中台的职责,再说日志中台之前,我们先扯点别的?

相信大家对集中式日志平台 ELK 都知道一些,生产环境中, 稍复杂的架构,服务一般都是集群部署,这样,日志就会分散在每台服务器上,一旦发生问题,想要查看日志就会非常繁琐,你需要登录每台服务器找日志,因为你不确定请求被打到哪个节点上。另外,任由开发人员登录服务器查看日志本身就存在安全隐患,不小心执行了 rm -rf * 咋办?

通过 ELK , 我们可以方便的将日志收集到一处(Elasticsearch 集群)来进行多维度的分析。

但是部署高性能、高可用的 ELK 是有门槛的,业务组想要快速的拥有集中式日志分析的能力,往往需要经过前期的技术调研,测试,踩坑,才能将这个平台搭建起来。

日志中台的使命就是让业务线能够快速拥有这种能力,只需傻瓜式的在日志平台完成接入操作即可。

臭嗨!说了这么多,跟你这篇文章的主题有啥关系?

额,小哈这就进入主题。

既然想统一管理日志,总得将这些分散的日志采集起来吧,那么,就需要一个日志采集器,LogstashFilebeat 都有采集日志的能力,但是 Filebeat 相较于 Logstash 的笨重, 它更轻量级,几乎零占用服务器系统资源,这里我们选型 Filebeat

业务组在日志平台完成相关接入流程后,平台会提供一个采集器包。接入方需要做的就是,下载这个采集器包并扔到指定服务器上,解压运行,即可开始采集日志,然后,就可以在日志平台的管控页面分析&搜索这些被收集的日志了。

这个 Filebeat 采集器包里面,包含了采集日志文件路径,输出到 Kafka 集群,以及一些个性化的采集规则等等。

怎么样?是不是感觉很棒呢?

二、如何通过 Java 打包文件?

2.1 添加 Maven 依赖

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

2.2 打包核心代码

通过 Apache compress 工具打包思路大致如下:

①:创建一个 FileOutputStream 到输出文件(.tar.gz)文件。

②:创建一个GZIPOutputStream,用来包装FileOutputStream对象。

③:创建一个TarArchiveOutputStream,用来包装GZIPOutputStream对象。

④:接着,读取文件夹中的所有文件。

⑤:如果是目录,则将其添加到 TarArchiveEntry

⑥:如果是文件,依然将其添加到 TarArchiveEntry 中,然后还需将文件内容写入 TarArchiveOutputStream 中。

接下来,直接上代码:

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.zip.GZIPOutputStream;

/**
 * @author 犬小哈 (公众号: 小哈学Java)
 * @date 2019-07-15
 * @time 16:15
 * @discription
 **/
public class TarUtils {

    /**
     * 压缩
     * @param sourceFolder 指定打包的源目录
     * @param tarGzPath 指定目标 tar 包的位置
     * @return
     * @throws IOException
     */
    public static void compress(String sourceFolder, String tarGzPath) throws IOException {
        createTarFile(sourceFolder, tarGzPath);
    }

    private static void createTarFile(String sourceFolder, String tarGzPath) {
        TarArchiveOutputStream tarOs = null;
        try {
            // 创建一个 FileOutputStream 到输出文件(.tar.gz)
            FileOutputStream fos = new FileOutputStream(tarGzPath);
            // 创建一个 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(sourceFolder, "", tarOs);
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                tarOs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void addFilesToTarGZ(String filePath, String parent, TarArchiveOutputStream tarArchive) throws IOException {
        File file = new File(filePath);
        // Create entry name relative to parent file path
        String entryName = parent + file.getName();
        // 添加 tar ArchiveEntry
        tarArchive.putArchiveEntry(new TarArchiveEntry(file, entryName));
        if (file.isFile()) {
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            // 写入文件
            IOUtils.copy(bis, tarArchive);
            tarArchive.closeArchiveEntry();
            bis.close();
        } else if (file.isDirectory()) {
            // 因为是个文件夹,无需写入内容,关闭即可
            tarArchive.closeArchiveEntry();
            // 读取文件夹下所有文件
            for (File f : file.listFiles()) {
                // 递归
                addFilesToTarGZ(f.getAbsolutePath(), entryName + File.separator, tarArchive);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        // 测试一波,将 filebeat-7.1.0-linux-x86_64 打包成名为 filebeat-7.1.0-linux-x86_64.tar.gz 的 tar 包
        compress("/Users/a123123/Work/filebeat-7.1.0-linux-x86_64", "/Users/a123123/Work/tmp_files/filebeat-7.1.0-linux-x86_64.tar.gz");
    }

}

至于,代码每行的作用,小伙伴们可以看代码注释,说的已经比较清楚了。

接下来,执行 main 方法,测试一下效果,看看打包是否成功:

生成采集器 tar.gz 包成功后,业务组只需将 tar.gz 下载下来,并扔到指定服务器,解压运行即可完成采集任务啦~

三、结语

本文主要还是介绍如何通过 Java 来完成打包功能,关于 ELK 相关的知识,小哈会在后续的文章中分享给大家,本文只是提及一下,欢迎小伙伴们持续关注哟,下期见~

到此这篇关于使用Java 压缩文件打包tar.gz 包的详细教程的文章就介绍到这了,更多相关Java 压缩文件打包tar.gz 包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java性能优化之编译器版本与平台对应关系

    java性能优化之编译器版本与平台对应关系

    这篇文章主要介绍了java性能优化--编译器版本与平台对应关系,本章节更加具体化的学习编译器还有哪些可以优化的方便,让你的应用展现出更好的性能,需要的朋友可以参考下
    2022-06-06
  • Java算法设计与分析分治算法

    Java算法设计与分析分治算法

    这篇文章主要介绍了Java算法设计与分析分治算法,一般分治算法在正文中分解为两个即以上的递归调用,并且子类问题一般是不想交的
    2022-07-07
  • java常用的加密解决方案分享

    java常用的加密解决方案分享

    这篇文章全面介绍了Java中加解密技术的应用,包括哈希函数、对称加密、非对称加密、消息认证码和数字签名等,它详细解释了每种技术的工作原理,并提供了相应的Java代码示例,文章还强调了密钥管理的重要性,并提出了在实际应用中遵循的最佳实践
    2025-01-01
  • 如何在java中使用SFTP协议安全的传输文件

    如何在java中使用SFTP协议安全的传输文件

    这篇文章主要介绍了如何在java中使用SFTP协议安全的传输文件,帮助大家更好的理解和使用JSch,感兴趣的朋友可以了解下
    2020-10-10
  • Java实现图片验证码功能

    Java实现图片验证码功能

    这篇文章主要为大家详细介绍了Java实现图片验证码功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • mybatis中Oracle参数为NULL错误问题及解决

    mybatis中Oracle参数为NULL错误问题及解决

    这篇文章主要介绍了mybatis中Oracle参数为NULL错误问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Java生成含字母和数字的6位随机字符串

    Java生成含字母和数字的6位随机字符串

    这篇文章主要为大家详细介绍了Java生成含字母和数字的6位随机字符串的相关资料,供大家参考,感兴趣的朋友可以参考一下
    2016-05-05
  • springcloud本地配置优先方式

    springcloud本地配置优先方式

    这篇文章主要介绍了springcloud本地配置优先方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • JavaFX实现简易时钟效果(一)

    JavaFX实现简易时钟效果(一)

    这篇文章主要为大家详细介绍了JavaFX实现简易时钟效果的第一篇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • 如何开发基于Netty的HTTP/HTTPS应用程序

    如何开发基于Netty的HTTP/HTTPS应用程序

    HTTP/HTTPS是最常见的协议套件之一,并且随着智能手机的成功,它的应用也日益广泛,因为对于任何公司来说,拥有一个可以被移动设备访问的网站几乎是必须的。下面就来看看如何开发基于Netty的HTTP/HTTPS应用程序
    2021-06-06

最新评论