Skip to content

Commit 52adae9

Browse files
Initial commit
1 parent 0bb08b3 commit 52adae9

File tree

4 files changed

+181
-0
lines changed

4 files changed

+181
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/.gradle
2+
/.idea
3+
/build
4+
/gradle
5+
/run
6+
gradlew
7+
gradlew.bat

build.gradle

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
plugins {
2+
id 'java'
3+
}
4+
5+
group 'com.tcoded'
6+
version '1.0-SNAPSHOT'
7+
8+
repositories {
9+
mavenCentral()
10+
}
11+
12+
dependencies {
13+
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
14+
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
15+
}
16+
17+
test {
18+
useJUnitPlatform()
19+
}
20+
jar {
21+
manifest {
22+
attributes 'Main-Class': 'com.tcoded.SimpleUnzipper'
23+
}
24+
}

settings.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rootProject.name = 'SimpleUnzipper'
2+
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package com.tcoded;
2+
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.FileOutputStream;
6+
import java.io.IOException;
7+
import java.util.zip.ZipEntry;
8+
import java.util.zip.ZipInputStream;
9+
10+
public class SimpleUnzipper {
11+
12+
public static void main(String[] args) {
13+
System.out.println("-- Simpler Unzipper --");
14+
String zipFilePathName = args.length > 0 ? args[0] : null;
15+
String destDirectoryName = args.length > 1 ? args[1] : null;
16+
String verboseArg = args.length > 2 ? args[2] : "true";
17+
18+
// Parse input file
19+
File zipFile;
20+
File wd = new File(System.getProperty("user.dir"));
21+
if (zipFilePathName == null) {
22+
// Find first zip file in the dir and use that
23+
System.out.println("No zip file was specified, using the first one we find...");
24+
zipFile = findFirstZipFileInDir(wd);
25+
} else {
26+
zipFile = new File(wd, zipFilePathName);
27+
}
28+
29+
// Parse output folder
30+
File destDir;
31+
if (destDirectoryName == null) {
32+
destDir = wd;
33+
} else {
34+
destDir = new File(wd, destDirectoryName);
35+
}
36+
37+
// Parse verbose option
38+
boolean verbose = verboseArg.equals("true");
39+
40+
// Sanity checks
41+
String effectiveZipFileAbsPath = zipFile == null ? "NULL" : zipFile.getAbsolutePath();
42+
String effectiveDestDirAbsPath = destDir.getAbsolutePath();
43+
if (zipFile == null || !zipFile.exists()) {
44+
System.out.printf("Could not find the zip file specified (%s)%n", effectiveZipFileAbsPath);
45+
return;
46+
}
47+
if (!destDir.exists()) {
48+
System.out.printf("Could not find the destination folder specified (%s)%n", effectiveDestDirAbsPath);
49+
return;
50+
}
51+
if (!destDir.isDirectory()) {
52+
System.out.printf("The destination specified is not a folder (%s)%n", effectiveDestDirAbsPath);
53+
return;
54+
}
55+
56+
System.out.printf("Using source file: %s%n", effectiveZipFileAbsPath);
57+
System.out.printf("Using destination folder: %s%n", destDir.getAbsolutePath());
58+
59+
try {
60+
System.out.println();
61+
System.out.println("Unzipping file...");
62+
63+
unzip(zipFile, destDir, verbose);
64+
65+
System.out.println();
66+
System.out.println("-----");
67+
System.out.println("DONE!");
68+
System.out.println("-----");
69+
} catch (IOException e) {
70+
e.printStackTrace();
71+
}
72+
}
73+
74+
private static void unzip(File zipFile, File destDir, boolean verbose) throws IOException {
75+
byte[] buffer = new byte[1024];
76+
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
77+
78+
ZipEntry currentEntry;
79+
while ((currentEntry = zis.getNextEntry()) != null) {
80+
// Verbose
81+
if (verbose) System.out.printf(" - Unpacking %s", currentEntry.getName());
82+
83+
// Filter hidden folders
84+
// noinspection SpellCheckingInspection
85+
if (currentEntry.getName().startsWith("__MACOSX/")) {
86+
if (verbose) System.out.println(" (Skipping...)");
87+
continue;
88+
} else {
89+
if (verbose) System.out.println();
90+
}
91+
92+
// Safely unpack current entry to destination file
93+
File currentFile = safeNewFile(destDir, currentEntry);
94+
95+
// Is entry a folder
96+
if (currentEntry.isDirectory()) {
97+
if (currentFile.exists() && !currentFile.isDirectory())
98+
throw new IOException("File with the name \"%s\" already exists but isn't a folder!".formatted(currentEntry.getName()));
99+
else if (!currentFile.exists() && !currentFile.mkdirs()) {
100+
throw new IOException("Failed to create folder with the name \"%s\"!".formatted(currentEntry.getName()));
101+
}
102+
}
103+
104+
// Is entry a file
105+
else {
106+
// Ensure that the folder in which to place the file exists
107+
File parentFolder = currentFile.getParentFile();
108+
109+
if (!parentFolder.isDirectory() && !parentFolder.mkdirs()) {
110+
throw new IOException("Failed to create folder with the name \"%s\"!".formatted(currentEntry.getName()));
111+
}
112+
113+
// Write the file
114+
try (FileOutputStream fileOutputStream = new FileOutputStream(currentFile)) {
115+
int bufferLenth;
116+
while ((bufferLenth = zis.read(buffer)) > 0) {
117+
fileOutputStream.write(buffer, 0, bufferLenth);
118+
}
119+
} // auto-close fileOutputStream
120+
}
121+
}
122+
123+
zis.closeEntry();
124+
} // auto-close zis
125+
}
126+
127+
private static File findFirstZipFileInDir(File wd) {
128+
File[] files = wd.listFiles((a, b) -> b.endsWith(".zip"));
129+
if (files == null) files = new File[] {};
130+
for (File file : files) {
131+
return file;
132+
}
133+
return null;
134+
}
135+
136+
public static File safeNewFile(File destinationDir, ZipEntry zipEntry) throws IOException {
137+
File destFile = new File(destinationDir, zipEntry.getName());
138+
139+
String destDirPath = destinationDir.getCanonicalPath();
140+
String destFilePath = destFile.getCanonicalPath();
141+
142+
if (!destFilePath.startsWith(destDirPath + File.separator)) {
143+
throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
144+
}
145+
146+
return destFile;
147+
}
148+
}

0 commit comments

Comments
 (0)