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:
parent
8e247e172b
commit
4b5e5192d9
|
@ -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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
|
|
@ -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)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
lorem ipsum
|
||||||
|
dolor sit amet
|
Loading…
Reference in New Issue