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