How to append files to a .tar archive using Apache Commons Compress?
apache-commons-compress, archive, compression, java, tar
Solution
Finally I succeeded to do it using this post.
I created a copy of the tar archive and copied to entire content to it. Then I delete the old tar archive.
public void appendFileInTarArchive(String tarPath, String tarFileName, String file2WriteName, String file2WriteContent) throws AuthenticationException, IOException {
if (tarPath == null || tarFileName == null || tarFileName.isEmpty()) {
LOG.warn("The path or the name of the tar archive is null or empty.");
return;
}
final File tarFile = new File(tarPath, tarFileName);
final File fileToAdd = new File(tarPath, file2WriteName);
FileUtils.write(fileToAdd, file2WriteContent);
if (file2WriteName == null || file2WriteName.isEmpty()) {
LOG.warn("The name of the file to append in the archive is null or empty.");
return;
}
ArchiveStreamFactory asf = new ArchiveStreamFactory();
File tempFile = new File(tarPath, "tmpTar.tar");
tempFile.createNewFile();
try {
FileInputStream fis = new FileInputStream(tarFile);
ArchiveInputStream ais = asf.createArchiveInputStream(ArchiveStreamFactory.TAR, fis);
FileOutputStream fos = new FileOutputStream(tempFile);
ArchiveOutputStream aos = asf.createArchiveOutputStream(ArchiveStreamFactory.TAR, fos);
// copy the existing entries
ArchiveEntry nextEntry;
while ((nextEntry = ais.getNextEntry()) != null) {
aos.putArchiveEntry(nextEntry);
IOUtils.copy(ais, aos);
aos.closeArchiveEntry();
}
// create the new entry
TarArchiveEntry entry = new TarArchiveEntry(file2WriteName);
entry.setSize(fileToAdd.length());
aos.putArchiveEntry(entry);
IOUtils.copy(new FileInputStream(fileToAdd), aos);
aos.closeArchiveEntry();
aos.finish();
ais.close();
aos.close();
// copies the new file over the old
tarFile.delete();
tempFile.renameTo(tarFile);
} catch (ArchiveException e) {
LOG.error(e.getMessage(), e);
} catch (IOException e) {
LOG.error(e.getMessage(), e);
} finally {
FileUtils.deleteQuietly(fileToAdd);
}
}
Problem
I read How do I append files to a tar archive in java?, append files to an archive without reading/rewriting the whole archive and Add an entry to a tar file without overwriting its existing contents but no good answer was given. Moreover I do not have enough reputation to post comments. So I created a new question here. Is there a way to append a file in a tar archive? I would like to replace a file if it exists already. I have started to write the following method but when the file is added, it erases the archive content. I didn't find any example on the apache compress website. ``` static final Logger LOG = Logger.getLogger(ShellClient.class); public void appendFileInTarArchive(String tarPath, String tarFileName, String file2WriteName, String file2WriteContent) throws IOException { if (tarPath == null || tarFileName == null || tarFileName.isEmpty()) { LOG.warn("The path or the name of the tar archive is null or empty."); return; } final File tarFile = new File(tarPath, tarFileName); final File fileToAdd = new File(tarPath, file2WriteName); FileUtils.write(fileToAdd, file2WriteContent); if (file2WriteName == null || file2WriteName.isEmpty()) { LOG.warn("The name of the file to append in the archive is null or empty."); return; } TarArchiveOutputStream aos = null; OutputStream out = null; try { out = new FileOutputStream(tarFile); aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.TAR, out); // create a new entry final TarArchiveEntry entry = new TarArchiveEntry(fileToAdd); entry.setSize(fileToAdd.length()); // add the entry to the archive aos.putArchiveEntry(entry); InputStream is = new FileInputStream(fileToAdd); final int byteCopied = IOUtils.copy(is, aos); if (LOG.isDebugEnabled()) { LOG.debug(byteCopied+" bytes inserted in the tar archive from "+fileToAdd); } is.close(); aos.closeArchiveEntry(); aos.finish(); aos.flush(); aos.close(); out.flush(); out.close(); } catch (ArchiveException e) { LOG.error(e.getMessage(), e); } catch (IOException e) { LOG.error(e.getMessage(), e); } finally { IOUtils.closeQuietly(aos); IOUtils.closeQuietly(out); FileUtils.deleteQuietly(fileToAdd); } } ```