Have you ever had to extract a large number of compressed files, but wanted to keep them organized in specific subdirectories? Manually extracting each file can be time-consuming and error-prone, especially if you have to do it for hundreds or thousands of files. In this tutorial, we’ll show you how to use JShell to automate the process of extracting compressed files into their corresponding subdirectories.
Prerequisites
Before we begin, you’ll need to have the following:
- Java Development Kit (JDK) 9 or later installed on your system
- Basic familiarity with the command line
- Some compressed files to extract (in this example, we’ll use ZIP, GZIP, and TAR files)
Step 1: Launch JShell
JShell is an interactive Java shell that allows you to test and run Java code snippets without having to create a full Java program. To launch JShell, open a command prompt or terminal window and enter the following command:
jshell
Once you see the JShell prompt (which looks like “jshell>”), you’re ready to start entering Java code.
Step 2: Define the Root Directory
The first thing we need to do is define the root directory that we want to search for compressed files. In our example, we’ll use the directory “/path/to/root/directory”. Replace this with the path to the directory that you want to search.
Path root = Paths.get("/path/to/root/directory");
Step 3: Define a Method to Extract Compressed Files
Next, we’ll define a method that can extract a compressed file to its corresponding subdirectory. This method will take a Path
object representing the compressed file as its argument.
void extractCompressedFile(Path compressedFile) {
// Code for extracting the file goes here
}
Inside this method, we’ll determine the subdirectory to extract the file to based on the name of the compressed file. We’ll then create the subdirectory if it doesn’t already exist, and extract the file based on its type (ZIP, GZIP, or TAR).
We’ll use the Apache Commons Compress library to handle different types of compressed files. You will need to download and include the library in your classpath in order for this script to work.
Here’s the full code for the extractCompressedFile
method:
import java.io.*;
import java.nio.file.*;
import java.util.zip.*;
import org.apache.commons.compress.archivers.*;
import org.apache.commons.compress.archivers.tar.*;
import org.apache.commons.compress.compressors.gzip.*;
// Define the root directory to search
Path root = Paths.get("/path/to/root/directory");
// Define a method to extract a compressed file to its corresponding subdirectory
void extractCompressedFile(Path compressedFile) {
try {
// Determine the subdirectory to extract the file to
Path subdirectory = compressedFile.getParent().resolve(compressedFile.getFileName().toString().replaceAll("\\.(zip|gz|tar)$", ""));
// Create the subdirectory if it doesn't already exist
Files.createDirectories(subdirectory);
// Extract the file based on its type
if (compressedFile.toString().endsWith(".zip")) {
ZipFile zipFile = new ZipFile(compressedFile.toFile());
zipFile.stream().forEach(entry -> {
try {
Path outputPath = subdirectory.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(outputPath);
} else {
InputStream inputStream = zipFile.getInputStream(entry);
Files.copy(inputStream, outputPath, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
e.printStackTrace();
}
});
zipFile.close();
} else if (compressedFile.toString().endsWith(".gz")) {
FileInputStream inputStream = new FileInputStream(compressedFile.toFile());
GzipCompressorInputStream gzInputStream = new GzipCompressorInputStream(inputStream);
Files.copy(gzInputStream, subdirectory.resolve(compressedFile.getFileName().toString().replaceAll("\\.gz$", "")), StandardCopyOption.REPLACE_EXISTING);
gzInputStream.close();
} else if (compressedFile.toString().endsWith(".tar")) {
FileInputStream inputStream = new FileInputStream(compressedFile.toFile());
TarArchiveInputStream tarInputStream = new TarArchiveInputStream(inputStream);
TarArchiveEntry entry = null;
while ((entry = tarInputStream.getNextTarEntry()) != null) {
Path outputPath = subdirectory.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(outputPath);
} else {
Files.copy(tarInputStream, outputPath, StandardCopyOption.REPLACE_EXISTING);
}
}
tarInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Define a method to traverse the directory and extract compressed files
void traverseDirectory(Path directory) {
try {
// Iterate over the contents of the directory
DirectoryStream<Path> stream = Files.newDirectoryStream(directory);
for (Path path : stream) {
if (Files.isDirectory(path)) {
// Recursively traverse subdirectories
traverseDirectory(path);
} else if (path.toString().matches(".*\\.(zip|gz|tar)$")) {
// Extract compressed files
extractCompressedFile(path);
}
}
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Call the traverseDirectory method with the root directory as the argument
traverseDirectory(root);