This is an automated email from the ASF dual-hosted git repository. bodewig pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-compress.git
The following commit(s) were added to refs/heads/master by this push: new e0d4555 add TarFile special case to Lister and Expander e0d4555 is described below commit e0d455582500ad0ff70dbb89b02d875ebd70b110 Author: Stefan Bodewig <bode...@apache.org> AuthorDate: Sat Jun 5 08:57:41 2021 +0200 add TarFile special case to Lister and Expander --- .../apache/commons/compress/archivers/Lister.java | 14 +++++++++ .../compress/archivers/examples/Expander.java | 31 ++++++++++++++++++-- .../commons/compress/archivers/tar/TarFile.java | 12 +++++++- .../compress/archivers/examples/ExpanderTest.java | 34 ++++++++++++++++++++++ 4 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/compress/archivers/Lister.java b/src/main/java/org/apache/commons/compress/archivers/Lister.java index 0b65199..e50020f 100644 --- a/src/main/java/org/apache/commons/compress/archivers/Lister.java +++ b/src/main/java/org/apache/commons/compress/archivers/Lister.java @@ -25,6 +25,8 @@ import java.io.InputStream; import java.nio.file.Files; import java.util.Enumeration; import org.apache.commons.compress.archivers.sevenz.SevenZFile; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarFile; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipFile; @@ -55,6 +57,8 @@ public final class Lister { list7z(f); } else if ("zipfile".equals(format)) { listZipUsingZipFile(f); + } else if ("tarfile".equals(format)) { + listZipUsingTarFile(f); } else { listStream(f, args); } @@ -106,9 +110,19 @@ public final class Lister { } } + private static void listZipUsingTarFile(final File f) throws ArchiveException, IOException { + try (TarFile t = new TarFile(f)) { + System.out.println("Created " + t.toString()); + for (TarArchiveEntry en : t.getEntries()) { + System.out.println(en.getName()); + } + } + } + private static void usage() { System.out.println("Parameters: archive-name [archive-type]\n"); System.out.println("the magic archive-type 'zipfile' prefers ZipFile over ZipArchiveInputStream"); + System.out.println("the magic archive-type 'tarfile' prefers TarFile over TarArchiveInputStream"); } } diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/Expander.java b/src/main/java/org/apache/commons/compress/archivers/examples/Expander.java index 1902a8b..bbbae00 100644 --- a/src/main/java/org/apache/commons/compress/archivers/examples/Expander.java +++ b/src/main/java/org/apache/commons/compress/archivers/examples/Expander.java @@ -29,12 +29,15 @@ import java.nio.channels.SeekableByteChannel; import java.nio.file.Files; import java.nio.file.StandardOpenOption; import java.util.Enumeration; +import java.util.Iterator; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.archivers.sevenz.SevenZFile; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarFile; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.utils.IOUtils; @@ -237,12 +240,14 @@ public class Expander { try (CloseableConsumerAdapter c = new CloseableConsumerAdapter(closeableConsumer)) { if (!prefersSeekableByteChannel(format)) { expand(format, c.track(Channels.newInputStream(archive)), targetDirectory); + } else if (ArchiveStreamFactory.TAR.equalsIgnoreCase(format)) { + expand(c.track(new TarFile(archive)), targetDirectory); } else if (ArchiveStreamFactory.ZIP.equalsIgnoreCase(format)) { expand(c.track(new ZipFile(archive)), targetDirectory); } else if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) { expand(c.track(new SevenZFile(archive)), targetDirectory); } else { - // never reached as prefersSeekableByteChannel only returns true for ZIP and 7z + // never reached as prefersSeekableByteChannel only returns true for TAR, ZIP and 7z throw new ArchiveException("Don't know how to handle format " + format); } } @@ -274,6 +279,26 @@ public class Expander { * @param targetDirectory the directory to write to * @throws IOException if an I/O error occurs * @throws ArchiveException if the archive cannot be read for other reasons + * @since 1.21 + */ + public void expand(final TarFile archive, final File targetDirectory) + throws IOException, ArchiveException { + final Iterator<TarArchiveEntry> entryIterator = archive.getEntries().iterator(); + expand(() -> entryIterator.hasNext() ? entryIterator.next() : null, + (entry, out) -> { + try (InputStream in = archive.getInputStream((TarArchiveEntry) entry)) { + IOUtils.copy(in, out); + } + }, targetDirectory); + } + + /** + * Expands {@code archive} into {@code targetDirectory}. + * + * @param archive the file to expand + * @param targetDirectory the directory to write to + * @throws IOException if an I/O error occurs + * @throws ArchiveException if the archive cannot be read for other reasons */ public void expand(final ZipFile archive, final File targetDirectory) throws IOException, ArchiveException { @@ -311,7 +336,9 @@ public class Expander { } private boolean prefersSeekableByteChannel(final String format) { - return ArchiveStreamFactory.ZIP.equalsIgnoreCase(format) || ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format); + return ArchiveStreamFactory.TAR.equalsIgnoreCase(format) + || ArchiveStreamFactory.ZIP.equalsIgnoreCase(format) + || ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format); } private void expand(final ArchiveEntrySupplier supplier, final EntryWriter writer, final File targetDirectory) diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java index 148d573..15adb18 100644 --- a/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java +++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java @@ -89,7 +89,7 @@ public class TarFile implements Closeable { * @throws IOException when reading the tar archive fails */ public TarFile(final byte[] content) throws IOException { - this(new SeekableInMemoryByteChannel(content), TarConstants.DEFAULT_BLKSIZE, TarConstants.DEFAULT_RCDSIZE, null, false); + this(new SeekableInMemoryByteChannel(content)); } /** @@ -187,6 +187,16 @@ public class TarFile implements Closeable { /** * Constructor for TarFile. * + * @param content the content to use + * @throws IOException when reading the tar archive fails + */ + public TarFile(final SeekableByteChannel content) throws IOException { + this(content, TarConstants.DEFAULT_BLKSIZE, TarConstants.DEFAULT_RCDSIZE, null, false); + } + + /** + * Constructor for TarFile. + * * @param archive the seekable byte channel to use * @param blockSize the blocks size to use * @param recordSize the record size to use diff --git a/src/test/java/org/apache/commons/compress/archivers/examples/ExpanderTest.java b/src/test/java/org/apache/commons/compress/archivers/examples/ExpanderTest.java index e3aa0dd..1a9cf30 100644 --- a/src/test/java/org/apache/commons/compress/archivers/examples/ExpanderTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/examples/ExpanderTest.java @@ -36,6 +36,7 @@ import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.archivers.StreamingNotSupportedException; import org.apache.commons.compress.archivers.sevenz.SevenZFile; import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile; +import org.apache.commons.compress.archivers.tar.TarFile; import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.utils.IOUtils; import org.junit.Assert; @@ -147,6 +148,15 @@ public class ExpanderTest extends AbstractTestCase { } } + @Test + public void tarFileVersion() throws IOException, ArchiveException { + setupTar(); + try (TarFile f = new TarFile(archive)) { + new Expander().expand(f, resultDir); + } + verifyTargetDir(); + } + private void setup7z() throws IOException, ArchiveException { archive = new File(dir, "test.7z"); final File dummy = new File(dir, "x"); @@ -194,6 +204,30 @@ public class ExpanderTest extends AbstractTestCase { } } + private void setupTar() throws IOException, ArchiveException { + archive = new File(dir, "test.tar"); + final File dummy = new File(dir, "x"); + try (OutputStream o = Files.newOutputStream(dummy.toPath())) { + o.write(new byte[14]); + } + try (ArchiveOutputStream aos = ArchiveStreamFactory.DEFAULT + .createArchiveOutputStream("tar", Files.newOutputStream(archive.toPath()))) { + aos.putArchiveEntry(aos.createArchiveEntry(dir, "a")); + aos.closeArchiveEntry(); + aos.putArchiveEntry(aos.createArchiveEntry(dir, "a/b")); + aos.closeArchiveEntry(); + aos.putArchiveEntry(aos.createArchiveEntry(dir, "a/b/c")); + aos.closeArchiveEntry(); + aos.putArchiveEntry(aos.createArchiveEntry(dummy, "a/b/d.txt")); + aos.write("Hello, world 1".getBytes(StandardCharsets.UTF_8)); + aos.closeArchiveEntry(); + aos.putArchiveEntry(aos.createArchiveEntry(dummy, "a/b/c/e.txt")); + aos.write("Hello, world 2".getBytes(StandardCharsets.UTF_8)); + aos.closeArchiveEntry(); + aos.finish(); + } + } + private void setupZip(final String entry) throws IOException, ArchiveException { archive = new File(dir, "test.zip"); final File dummy = new File(dir, "x");