java tararchiveentry_Apache Commons Compress介绍-JAVA压缩解压tar文件

tar是一种很老的归档格式,最早可以追溯到UNIX时代,tar已成为POSIX标准之一。tar早期经常用于将文件拷贝到磁带上(这里的磁带可不是以前听歌用的磁带,而是早期计算机的存储截至),加上tar格式诞生时间很早,因此tar标准里面的很多设计今天看起来很奇怪。

对于tar格式,需要注意的是,它是一个“归档”(archive)格式。何谓归档?简单的说,就是把“散落”的文件都整齐的“码放”在一起。换句话说,tar格式只是单纯的把文件放在一起,并不能起到压缩的效果。常见的压缩格式如tar.gz,tar.bz2,tar.xz 等格式,其实是把文件通过tar放在一起之后,用gzip、bzip2、xz等工具再进行一次压缩得到的。

另外,tar格式的设计与zip、7zip等常见压缩格式有些不同-它没有类似“目录”的存在,这就导致很难做到zip、7zip一样只解压特定的文件(这种操作一般称作随机访问random access)而不去碰解压其他文件。Commons Compress对于tar格式也是这样设计的:它不提供类似ZipFile这样可以罗列所有文件的类和方法,只能按照文件在tar中的顺序去逐个遍历。

直接上例子:

解压全部文件

解压全部文件时可以通过TarArchiveInputStream.getNextTarEntry遍历所有文件并进行解压,比如我要将位于/root/test.tar位置的文件,全部解压到/tmp/output目录下,代码如下:

try (FileInputStream in = new FileInputStream(new File("/root/test.tar")));

TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(in)) {

byte[] buffer = new byte[4096];

TarArchiveEntry entry;

while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {

if (entry.isDirectory()) {

continue;

}

File outputFile = new File("/tmp/output/" + entry.getName());

if (!outputFile.getParentFile().exists()) {

outputFile.getParentFile().mkdirs();

}

try (FileOutputStream fos = new FileOutputStream(outputFile)) {

while (tarArchiveInputStream.read(buffer) > 0) {

fos.write(buffer);

}

}

}

}

解压特定文件

可以在遍历时,根据entry判断是否是需要解压的文件,比如需要将/root/test.tar压缩包中,文件名为targetFile的文件,解压到/tmp/output/targetFile文件中,代码如下:

try (FileInputStream in = new FileInputStream(getFile("bla.tar"));

TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(in)) {

byte[] buffer = new byte[4096];

TarArchiveEntry entry;

while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {

if (entry.isDirectory()) {

continue;

}

if (entry.getName() != "targetFile") {

continue;

}

File outputFile = new File("/tmp/output/" + entry.getName());

if (!outputFile.getParentFile().exists()) {

outputFile.getParentFile().mkdirs();

}

try (FileOutputStream fos = new FileOutputStream(outputFile)) {

while (tarArchiveInputStream.read(buffer) > 0) {

fos.write(buffer);

}

}

}

}

解压tar.gz文件

我前面说过,tar.gz文件是先把文件用tar归档以后用gzip进行压缩,因此解压tar.gz也就需要先解压gzip然后解压tar。说起来好像很复杂,实际上代码和解压tar文件几乎完全一样,只需要将输入的文件用GZIPInputStream包装一下即可:

try (FileInputStream in = new FileInputStream(new GZIPInputStream(new File("/root/test.tar.gz"))));

TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(in)) {

byte[] buffer = new byte[4096];

TarArchiveEntry entry;

while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {

if (entry.isDirectory()) {

continue;

}

File outputFile = new File("/tmp/output/" + entry.getName());

if (!outputFile.getParentFile().exists()) {

outputFile.getParentFile().mkdirs();

}

try (FileOutputStream fos = new FileOutputStream(outputFile)) {

while (tarArchiveInputStream.read(buffer) > 0) {

fos.write(buffer);

}

}

}

}

创建tar文件

比如我要在/tmp/output/目录下,创建一个test.tar,并在里面添加2个文件file1和file2,代码如下:

final File f = new File("/tmp/output/test.tar");

final FileOutputStream fos = new FileOutputStream(f);

final TarArchiveOutputStream tos = new TarArchiveOutputStream(fos);

TarArchiveEntry entry = new TarArchiveEntry("file1");

final String x = "this is content of file1\n";

entry.setSize(x.length());

tos.putArchiveEntry(entry);

tos.write(x.getBytes());

tos.closeArchiveEntry();

entry = new TarArchiveEntry("file2");

final String y = "this is content of file2\n";

entry.setSize(y.length());

tos.putArchiveEntry(entry);

tos.write(y.getBytes());

tos.closeArchiveEntry();

tos.close();

创建tar.gz文件

太简单了,几乎与创建tar文件类似,只需要将文件输出流用gzip输出流包装一下即可,还是用上面的例子:

final File f = new File("/tmp/output/test.tar.gz");

final FileOutputStream fos = new FileOutputStream(f);

final GzipCompressorOutputStream gzipos = new GzipCompressorOutputStream(fos);

final TarArchiveOutputStream tos = new TarArchiveOutputStream(gzipos);

TarArchiveEntry entry = new TarArchiveEntry("file1");

final String x = "this is content of file1\n";

entry.setSize(x.length());

tos.putArchiveEntry(entry);

tos.write(x.getBytes());

tos.closeArchiveEntry();

entry = new TarArchiveEntry("file2");

final String y = "this is content of file2\n";

entry.setSize(y.length());

tos.putArchiveEntry(entry);

tos.write(y.getBytes());

tos.closeArchiveEntry();

tos.close();

还有问题?

commons社区是一个开放的社区,可以在commons compress社区上提问- ASF JIRA​issues.apache.org

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Apache Commons Compress 是一个用于处理压缩文件的开源 Java 库,它支持多种压缩格式,包括 ZIP、TAR、GZIP、BZIP2 等。 下面是使用 Apache Commons Compress 实现文件压缩解压的示例代码: ## 压缩文件 ```java import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; public class FileCompressor { public static void compress(File source, File destination) throws Exception { try (FileOutputStream fos = new FileOutputStream(destination); GzipCompressorOutputStream gzos = new GzipCompressorOutputStream(fos); TarArchiveOutputStream tos = new TarArchiveOutputStream(gzos)) { ArchiveEntry entry = new TarArchiveEntry(source.getName()); entry.setSize(source.length()); tos.putArchiveEntry(entry); FileInputStream fis = new FileInputStream(source); byte[] buffer = new byte[4096]; int count; while ((count = fis.read(buffer)) != -1) { tos.write(buffer, 0, count); } fis.close(); tos.closeArchiveEntry(); } } } ``` ## 解压文件 ```java import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; public class FileExtractor { public static void extract(File source, File destination) throws Exception { try (FileInputStream fis = new FileInputStream(source); GzipCompressorInputStream gzis = new GzipCompressorInputStream(fis); ArchiveInputStream ais = new TarArchiveInputStream(gzis)) { ArchiveEntry entry; while ((entry = ais.getNextEntry()) != null) { if (!ais.canReadEntryData(entry)) { continue; } File file = new File(destination, entry.getName()); if (entry.isDirectory()) { file.mkdirs(); } else { FileOutputStream fos = new FileOutputStream(file); byte[] buffer = new byte[4096]; int count; while ((count = ais.read(buffer)) != -1) { fos.write(buffer, 0, count); } fos.close(); } } } } } ``` 以上是使用 Apache Commons Compress 实现文件压缩解压的示例代码,你可以根据自己的需求进行修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值