Add an entry to a tar file without overwriting its existing contents

Go To


I need to add a config file to an existing tar file. I am using apache.commons.compress library. The following code snippet adds the entry correctly but overwrites the existing entries of the tar file.

public static void injectFileToTar () throws IOException, ArchiveException {
        String agentSourceFilePath = "C:\\Work\\tar.gz\\";
        String fileToBeAdded = "activeSensor.cfg";
        String unzippedFileName = "sample.tar";

    File f2 = new File(agentSourceFilePath+unzippedFileName); // Refers to the .tar file
    File f3 = new File(agentSourceFilePath+fileToBeAdded);    // The new entry to be added to the .tar file

    // Injecting an entry in the tar
    OutputStream tarOut = new FileOutputStream(f2);
    TarArchiveOutputStream aos = (TarArchiveOutputStream) new  ArchiveStreamFactory().createArchiveOutputStream("tar", tarOut);
    TarArchiveEntry entry = new TarArchiveEntry(fileToBeAdded);
    FileInputStream fis = new FileInputStream(f3);
    IOUtils.copy(fis, aos);


On checking the tar, only "activeSensor.cfg" file is found and the initial content of the tar is found missing. Is the "mode" not set correctly ?

2012-04-04 07:34
by Ankit Sharma


The problem is that the TarArchiveOutputStream does not automatically read in the existing archive, which is something that you'd need to do. Something along the lines of:

CompressorStreamFactory csf = new CompressorStreamFactory();
ArchiveStreamFactory asf = new ArchiveStreamFactory();

String tarFilename = "test.tgz";
String toAddFilename = "activeSensor.cfg";
File toAddFile = new File(toAddFilename);
File tempFile = File.createTempFile("updateTar", "tgz");
File tarFile = new File(tarFilename);

FileInputStream fis = new FileInputStream(tarFile);
CompressorInputStream cis = csf.createCompressorInputStream(CompressorStreamFactory.GZIP, fis);
ArchiveInputStream ais = asf.createArchiveInputStream(ArchiveStreamFactory.TAR, cis);

FileOutputStream fos = new FileOutputStream(tempFile);
CompressorOutputStream cos = csf.createCompressorOutputStream(CompressorStreamFactory.GZIP, fos);
ArchiveOutputStream aos = asf.createArchiveOutputStream(ArchiveStreamFactory.TAR, cos);

// copy the existing entries    
ArchiveEntry nextEntry;
while ((nextEntry = ais.getNextEntry()) != null) {
    IOUtils.copy(ais, aos, (int)nextEntry.getSize());

// create the new entry
TarArchiveEntry entry = new TarArchiveEntry(toAddFilename);
IOUtils.copy(new FileInputStream(toAddFile), aos, (int)toAddFile.length());



// copies the new file over the old

A couple of notes:

  • This code does not include any exception handling (please add the appropriate try-catch-finally blocks)
  • This code does not handle files with a size over 2147483647 (Integer.MAX_VALUE) as it only reads file sizes to integer precision bytes (see the cast to int). However, that's not a problem as Apache Compress does not handle files over 2 GB anyway.
2012-04-04 09:16
by beny23
Thanks, it worked. I had to tweak the code slightly in the sense that I was not able to execute the entire code that you shared, directly on .tar.gz file format.

So I had to unzip the file first to arrive at .tar format. After injecting the required entry in the tar file as per the suggested manner, I had to re-zip it again.

For unzipping and re-zipping, I used and utilities - Ankit Sharma 2012-04-04 12:38


Try changing

OutputStream tarOut = new FileOutputStream(f2);


OutputStream tarOut = new FileOutputStream(f2, true); //Set append to true

2012-04-04 08:09
by biggusjimmus
@biggusjimmusThank - Ankit Sharma 2012-04-04 08:32
Thanks. I made the above change. The tar contents are retained but the new entry (activeSensor.cfg) does not get added to the tar. Am I messing something up with the path or the argument passed to the TarArchiveEntry constructor - Ankit Sharma 2012-04-04 08:44
I was using this approach before I went searching here. Seems that causes the entry to be put beyond the end of the tar archive, so I would get an error to that effect, but my new file wouldn't be there - froggythefrog 2017-05-11 02:09