Add entry to tar file without overwriting existing content

I need to add a configuration file to an existing tar file. I am using apache.commons.compress . The following code snippet adds the entry correctly, but overwrites the existing entries in 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); entry.setMode(0100000); entry.setSize(f3.length()); aos.putArchiveEntry(entry); FileInputStream fis = new FileInputStream(f3); IOUtils.copy(fis, aos); fis.close(); aos.closeArchiveEntry(); aos.finish(); aos.close(); tarOut.close(); 

}

When checking tar, only the file "activeSensor.cfg" was found, and the original contents of tar were not found. Is the "mode" set correctly?

+3
source share
2 answers

The problem is that TarArchiveOutputStream is not automatically read in the existing archive, what you need to do. Sort 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) { aos.putArchiveEntry(nextEntry); IOUtils.copy(ais, aos, (int)nextEntry.getSize()); aos.closeArchiveEntry(); } // create the new entry TarArchiveEntry entry = new TarArchiveEntry(toAddFilename); entry.setSize(toAddFile.length()); aos.putArchiveEntry(entry); IOUtils.copy(new FileInputStream(toAddFile), aos, (int)toAddFile.length()); aos.closeArchiveEntry(); aos.finish(); ais.close(); aos.close(); // copies the new file over the old tarFile.delete(); tempFile.renameTo(tarFile); 

A few notes:

  • This code does not include exception handling (add appropriate try-catch-finally blocks)
  • This code does not process files larger than 2147483647 ( Integer.MAX_VALUE ), since it only reads file sizes in bytes with integer dots (see conversion to int). However, this is not a problem, since Apache Compress does not process files larger than 2 GB in any case.
+2
source

Try to change

OutputStream tarOut = new FileOutputStream(f2);

to

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

0
source

Source: https://habr.com/ru/post/1439749/


All Articles