Java中的GZIP多个文件创建Tar存档

时间:2020-01-09 10:35:28  来源:igfitidea点击:

GZIP通常用于压缩GZIP格式的单个文件,如果要在Java中使用GZIP格式压缩多个文件,则需要两个步骤。

  • 首先将多个文件与tar一起存档,
  • 然后使用gzip压缩以创建.tar.gz压缩档案。

在本文中,我们将看到在Java中使用gzip压缩多个文件的整个过程,方法是在Java中创建一个tar文件,然后对其进行gzip压缩,从而创建一个.tar.gz归档文件。

Gzip Java中的多个文件

此处给出的Java程序可将多个文件存档到tar中,然后压缩为GZIP,使用Apache Commons Compress库,该库可从以下路径下载

此处使用的版本是commons-compress-1.18,因此commons-compress-1.18.jar已添加到类路径。

从Apache Commons Compress库中,有两个文件用于创建tar存档。

  • TarArchiveEntry –表示Tar归档文件中的条目。因此,使用TarArchiveEntry将所有压缩的目录和文件添加到tar存档中。
  • TarArchiveOutputStream –此类具有一些方法,用于放置存档条目,然后通过写入此流来写入文件的内容。 TarArchiveOutputStream将GZIPOutputStream包装在程序中。

Java程序–创建tar存档和Gzip多个文件

Java程序中使用的目录结构如下所示,有一个父目录测试,其中包含两个子目录docs和prints和四个文件

$ ls -R test

test:
aa.txt  bb.txt  docs  prints

test/docs:
display.txt

test/prints:
output

在程序中,我们需要遍历目录结构以存档所有文件和目录。如果它是目录,则只需归档该条目,就文件而言,除了归档该条目外,还将文件内容写入流中。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;

public class GZipMultipleFiles {
  public static void main(String[] args) {
    String PARENT_DIRECTORY = "/home/theitroad/Documents/test";
    GZipMultipleFiles gzipMultipleFiles = new GZipMultipleFiles();
    gzipMultipleFiles.createTarArchive(PARENT_DIRECTORY);
  }
	
  public void createTarArchive(String parentDir){
    TarArchiveOutputStream tarArchive = null;
    try {
      File root = new File(parentDir);
      // create output name for tar archive
      FileOutputStream fos = new FileOutputStream(root.getAbsolutePath().concat(".tar.gz"));
      GZIPOutputStream gzipOS = new GZIPOutputStream(new BufferedOutputStream(fos));
      tarArchive = new TarArchiveOutputStream(gzipOS);
      addToArchive(parentDir, "", tarArchive);   
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }finally{
      try {
        tarArchive.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
	
  public void addToArchive(String filePath, String parent, TarArchiveOutputStream tarArchive) throws IOException {
    File file = new File(filePath);
    // Create entry name relative to parent file path 
    //for the archived file
    String entryName = parent + file.getName();
    System.out.println("entryName " + entryName);
    // add tar ArchiveEntry
    tarArchive.putArchiveEntry(new TarArchiveEntry(file, entryName));
    if(file.isFile()){
      FileInputStream fis = new FileInputStream(file);
      BufferedInputStream bis = new BufferedInputStream(fis);
      // Write file content to archive
      IOUtils.copy(bis, tarArchive);
      tarArchive.closeArchiveEntry();
      bis.close();
    }else if(file.isDirectory()){
      // no content to copy so close archive entry
      tarArchive.closeArchiveEntry();
      // if this directory contains more directories and files
      // traverse and archive them 
      for(File f : file.listFiles()){		
        // recursive call
        addToArchive(f.getAbsolutePath(), entryName+File.separator, tarArchive);
      }
    }		  
  }
}

tar档案中条目的输出

entryName test
entryName test/docs
entryName test/docs/display.txt
entryName test/bb.txt
entryName test/prints
entryName test/prints/output
entryName test/aa.txt