You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2021/06/05 07:38:07 UTC
[commons-compress] branch master updated: add TarFile special case
to Lister and Expander
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 <bo...@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");