BAEL 7619 - Intro to the Apache Commons Compress Project (#16220)

* matcher.appendReplacement() takes a StringBuffer, not StringBuilder

* First draft

* review 1
This commit is contained in:
Ulisses Lima 2024-04-08 03:17:59 -03:00 committed by GitHub
parent 8e247e172b
commit 4b5e5192d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 297 additions and 4 deletions

View File

@ -44,15 +44,27 @@
<version>${mockftpserver.version}</version> <version>${mockftpserver.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>${xz.version}</version>
</dependency>
<dependency>
<groupId>com.github.luben</groupId>
<artifactId>zstd-jni</artifactId>
<version>${zstd-jni.version}</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
<commons-compress.version>1.23.0</commons-compress.version> <commons-compress.version>1.26.1</commons-compress.version>
<ant.version>1.10.13</ant.version> <ant.version>1.10.13</ant.version>
<commons-vfs2.version>2.9.0</commons-vfs2.version> <commons-vfs2.version>2.9.0</commons-vfs2.version>
<apache-commons-text.version>1.10.0</apache-commons-text.version> <apache-commons-text.version>1.10.0</apache-commons-text.version>
<commons-net.version>3.6</commons-net.version> <commons-net.version>3.6</commons-net.version>
<mockftpserver.version>2.7.1</mockftpserver.version> <mockftpserver.version>2.7.1</mockftpserver.version>
<xz.version>1.9</xz.version>
<zstd-jni.version>1.5.5-11</zstd-jni.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,119 @@
package com.baeldung.commons.compress;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
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.ArchiveOutputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.examples.Archiver;
import org.apache.commons.compress.archivers.examples.Expander;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorInputStream;
import org.apache.commons.compress.compressors.CompressorOutputStream;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.compress.utils.FileNameUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
public class CompressUtils {
private CompressUtils() {
}
public static void archive(Path directory, Path destination) throws IOException, ArchiveException {
String format = FileNameUtils.getExtension(destination);
new Archiver().create(format, destination, directory);
}
public static void archiveAndCompress(String directory, Path destination) throws IOException, ArchiveException, CompressorException {
archiveAndCompress(Paths.get(directory), destination);
}
public static void archiveAndCompress(Path directory, Path destination) throws IOException, ArchiveException, CompressorException {
String compressionFormat = FileNameUtils.getExtension(destination);
String archiveFormat = FilenameUtils.getExtension(destination.getFileName()
.toString()
.replace("." + compressionFormat, ""));
try (OutputStream archive = Files.newOutputStream(destination);
BufferedOutputStream archiveBuffer = new BufferedOutputStream(archive);
CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(compressionFormat, archiveBuffer);
ArchiveOutputStream<?> archiver = new ArchiveStreamFactory().createArchiveOutputStream(archiveFormat, compressor)) {
new Archiver().create(archiver, directory);
}
}
public static void decompress(Path file, Path destination) throws IOException, ArchiveException, CompressorException {
decompress(Files.newInputStream(file), destination);
}
public static void decompress(InputStream file, Path destination) throws IOException, ArchiveException, CompressorException {
try (InputStream in = file;
BufferedInputStream inputBuffer = new BufferedInputStream(in);
OutputStream out = Files.newOutputStream(destination);
CompressorInputStream decompressor = new CompressorStreamFactory().createCompressorInputStream(inputBuffer)) {
IOUtils.copy(decompressor, out);
}
}
public static void extract(Path archive, Path destination) throws IOException, ArchiveException, CompressorException {
new Expander().expand(archive, destination);
}
public static void compressFile(Path file, Path destination) throws IOException, CompressorException {
String format = FileNameUtils.getExtension(destination);
try (OutputStream out = Files.newOutputStream(destination);
BufferedOutputStream buffer = new BufferedOutputStream(out);
CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(format, buffer)) {
IOUtils.copy(Files.newInputStream(file), compressor);
}
}
public static void zip(Path file, Path destination) throws IOException {
try (InputStream input = Files.newInputStream(file);
OutputStream output = Files.newOutputStream(destination);
ZipArchiveOutputStream archive = new ZipArchiveOutputStream(output)) {
archive.setLevel(Deflater.BEST_COMPRESSION);
archive.setMethod(ZipEntry.DEFLATED);
archive.putArchiveEntry(new ZipArchiveEntry(file.getFileName()
.toString()));
IOUtils.copy(input, archive);
archive.closeArchiveEntry();
}
}
public static void extractOne(Path archivePath, String fileName, Path destinationDirectory) throws IOException, ArchiveException {
try (InputStream input = Files.newInputStream(archivePath);
BufferedInputStream buffer = new BufferedInputStream(input);
ArchiveInputStream<?> archive = new ArchiveStreamFactory().createArchiveInputStream(buffer)) {
ArchiveEntry entry;
while ((entry = archive.getNextEntry()) != null) {
if (entry.getName()
.equals(fileName)) {
Path outFile = destinationDirectory.resolve(fileName);
Files.createDirectories(outFile.getParent());
try (OutputStream os = Files.newOutputStream(outFile)) {
IOUtils.copy(archive, os);
}
break;
}
}
}
}
}

View File

@ -1,10 +1,10 @@
package com.baeldung.commons.convertunicode; package com.baeldung.commons.convertunicode;
import org.apache.commons.text.StringEscapeUtils;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.text.StringEscapeUtils;
public class UnicodeConverterUtil { public class UnicodeConverterUtil {
public static String decodeWithApacheCommons(String input) { public static String decodeWithApacheCommons(String input) {
@ -15,7 +15,7 @@ public class UnicodeConverterUtil {
Pattern pattern = Pattern.compile("\\\\u[0-9a-fA-F]{4}"); Pattern pattern = Pattern.compile("\\\\u[0-9a-fA-F]{4}");
Matcher matcher = pattern.matcher(input); Matcher matcher = pattern.matcher(input);
StringBuilder decodedString = new StringBuilder(); StringBuffer decodedString = new StringBuffer();
while (matcher.find()) { while (matcher.find()) {
String unicodeSequence = matcher.group(); String unicodeSequence = matcher.group();

View File

@ -0,0 +1,135 @@
package com.baeldung.commons.compress;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class CompressUtilsUnitTest {
static Path TMP;
static String ZIP_FILE = "new.txt.zip";
static String COMPRESSED_FILE = "new.txt.gz";
static String DECOMPRESSED_FILE = "decompressed-file.txt";
static String DECOMPRESSED_ARCHIVE = "decompressed-archive.tar";
static String COMPRESSED_ARCHIVE = "archive.tar.gz";
static String MODIFIED_ARCHIVE = "modified-archive.tar";
static String EXTRACTED_DIR = "extracted";
@BeforeAll
static void setup() throws IOException {
TMP = Files.createTempDirectory("compress-test")
.toAbsolutePath();
}
@AfterAll
static void destroy() throws IOException {
FileUtils.deleteDirectory(TMP.toFile());
}
@Test
@Order(1)
void givenFile_whenCompressing_thenCompressed() throws IOException, CompressorException, URISyntaxException {
Path destination = TMP.resolve(COMPRESSED_FILE);
CompressUtils.compressFile(TestResources.testFile(), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(2)
void givenFile_whenZipping_thenZipFileCreated() throws IOException, URISyntaxException {
Path destination = TMP.resolve(ZIP_FILE);
CompressUtils.zip(TestResources.testFile(), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(3)
void givenCompressedArchive_whenDecompressing_thenArchiveAvailable() throws IOException, ArchiveException, CompressorException {
Path destination = TMP.resolve(DECOMPRESSED_ARCHIVE);
CompressUtils.decompress(TestResources.compressedArchive(), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(4)
void givenCompressedFile_whenDecompressing_thenFileAvailable() throws IOException, ArchiveException, CompressorException {
Path destination = TMP.resolve(DECOMPRESSED_FILE);
CompressUtils.decompress(TMP.resolve(COMPRESSED_FILE), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(5)
void givenDecompressedArchive_whenUnarchiving_thenFilesAvailable() throws IOException, ArchiveException, CompressorException {
Path destination = TMP.resolve(EXTRACTED_DIR);
CompressUtils.extract(TMP.resolve(DECOMPRESSED_ARCHIVE), destination);
assertTrue(Files.isDirectory(destination));
}
@Test
@Order(6)
void givenDirectory_whenArchivingAndCompressing_thenCompressedArchiveAvailable() throws IOException, ArchiveException, CompressorException {
Path destination = TMP.resolve(COMPRESSED_ARCHIVE);
CompressUtils.archiveAndCompress(TMP.resolve(EXTRACTED_DIR), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(7)
void givenExistingArchive_whenAddingSingleEntry_thenArchiveModified() throws IOException, ArchiveException, CompressorException, URISyntaxException {
Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE);
Path newArchive = TMP.resolve(MODIFIED_ARCHIVE);
Path tmpDir = TMP.resolve(newArchive + "-tmpd");
Path newEntry = TestResources.testFile();
CompressUtils.extract(archive, tmpDir);
assertTrue(Files.isDirectory(tmpDir));
Files.copy(newEntry, tmpDir.resolve(newEntry.getFileName()));
CompressUtils.archive(tmpDir, newArchive);
assertTrue(Files.isRegularFile(newArchive));
FileUtils.deleteDirectory(tmpDir.toFile());
Files.delete(archive);
Files.move(newArchive, archive);
assertTrue(Files.isRegularFile(archive));
}
@Test
@Order(8)
void givenExistingArchive_whenExtractingSingleEntry_thenFileExtracted() throws IOException, ArchiveException {
Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE);
String targetFile = "sub/other.txt";
CompressUtils.extractOne(archive, targetFile, TMP);
assertTrue(Files.isRegularFile(TMP.resolve(targetFile)));
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.commons.compress;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
public interface TestResources {
String DIR = "/compress/";
static InputStream compressedArchive() {
return TestResources.class.getResourceAsStream(DIR + CompressUtilsUnitTest.COMPRESSED_ARCHIVE);
}
static Path testFile() throws URISyntaxException {
URL resource = TestResources.class.getResource(DIR + "new.txt");
if (resource == null) {
throw new IllegalArgumentException("file not found!");
} else {
return Paths.get(resource.toURI());
}
}
}

View File

@ -0,0 +1,2 @@
lorem ipsum
dolor sit amet