Pages

03/08/2015

[Java] Tar file or folders

A simple way to tar a file or folder (with or without subdirectories) maintaining the folders structure is using the Apache Commons Compress library.

 import java.io.File;  
 import java.io.FileInputStream;  
 import java.io.FileOutputStream;  
 import java.io.OutputStream;  
 import java.nio.file.Files;  
   
 import org.apache.commons.compress.archivers.ArchiveOutputStream;  
 import org.apache.commons.compress.archivers.ArchiveStreamFactory;  
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;  
 import org.apache.commons.compress.utils.IOUtils;  
   
 public void tar(String location, String name, String tarlocation, String tarname){   
      //method variables   
      private OutputStream out;  
      private ArchiveOutputStream tar_out;  
      private FileInputStream tmp_fis;  
   
      //out writes the final file, tar_out creates the tar archive   
      out = new FileOutputStream(new File(tarlocation+File.separator+tarname+".tar"));   
      tar_out = new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.TAR, out);   
      //tar it   
      File f = new File(location+File.separator+name);   
      //first time baseDir is empty   
      dotar(f, "");   
      //close archive   
      tar_out.finish();    
      out.close();   
 }   
   
 //aux method for tarring  
 private void dotar(File myFile, String baseDir) throws Exception{  
      //maintain the directory structure while tarring  
      String entryName = baseDir+myFile.getName();  
      //DO NOT do a putArchiveEntry for folders as it is not needed  
      //if it's a directory then list and tar the contents. Uses recursion for nested directories  
      if(myFile.isDirectory() == true){  
           File[] filesList = myFile.listFiles();  
           if(filesList != null){  
                for (File file : filesList) {  
                     dotar(file, entryName+File.separator);  
                }  
           }  
      }  
      else{  
           //add file  
           tmp_fis = new FileInputStream(myFile);  
           try{  
                tar_out.putArchiveEntry(new TarArchiveEntry(myFile, entryName));  
                IOUtils.copy(tmp_fis, tar_out);  
                tar_out.closeArchiveEntry();  
           }  
           catch(Exception e){  
                throw e;  
           }  
           finally{  
                if(tmp_fis != null) tmp_fis.close();  
           }  
      }  
 }   


It has to be recursive so that we can handle subdirectories correctly. The resulting tarred file will untar to the same exact folder structure originally tarred. If you pass the location and tarlocation parameters with the path separator already appended, there's no need to concatenate File.separator in the code.

No comments:

Post a Comment

With great power comes great responsibility