Hello EZ.
Since I needed a similar class for my current project, I thought that might come in handy for others too.
This code demonstrates how to zip or unzip files with Java. I wrote some comments for the public methods, so I hope it is understandable (if not, you know where to ask).
I didn't really handle exceptions, because it is not meant as a tool, but as example.
Usage:
Compile: javac ZipCompression.java
Zip: java ZipCompression -a <directory>
Unzip: java ZipCompression -x <zipfile>
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.DirectoryIteratorException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipCompression {
private final static String SEP = System.getProperty("file.separator");
public static void main(String[] args) throws FileNotFoundException,
IOException {
if (args.length != 2
|| (!args[0].equals("-x") && !args[0].equals("-a"))) {
printUsage();
} else {
if (args[0].equals("-a")) {
zip(args[1]);
} else {
unzip(args[1]);
}
}
}
/**
* Creates a zip archive with inFiles as entries.
*
* @param inFiles
* files that shall be put to the archive
* @param outFile
* zip archive that shall be created
* @throws FileNotFoundException
* @throws IOException
*/
public static void zip(Set<Path> inFiles, Path outFile)
throws FileNotFoundException, IOException {
System.out.println("creating zip file " + outFile);
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(
outFile.toString())) ;) {
zip(inFiles, "", zout);
}
}
/**
* Extracts all files in zipFile to the destination directory.
*
* @param zipFile
* archive to extract
* @param destinationDir
* directory, where the files shall be written to
* @throws FileNotFoundException
* @throws IOException
*/
public static void unzip(Path zipFile, Path destinationDir)
throws FileNotFoundException, IOException {
System.out.println("extracting zip file " + zipFile);
try (ZipInputStream zin = new ZipInputStream(new FileInputStream(
zipFile.toString()))) {
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
extractEntry(destinationDir, zin, entry);
}
}
}
/**
* Creates a zip archive for all files in the given directory. The name of
* the archive will be the directory name with the ending '.zip' and is
* created in the parent directory.
*
* @param directoryName
* directory that shall be zipped
* @throws FileNotFoundException
* @throws IOException
*/
public static void zip(String directoryName) throws FileNotFoundException,
IOException {
Path dir = Paths.get(directoryName);
Set<Path> inFiles = getDirectoryFiles(dir);
Path outFile = Paths.get(dir.toString() + ".zip");
zip(inFiles, outFile);
}
private static void zip(Set<Path> inFiles, String base, ZipOutputStream zout)
throws IOException, FileNotFoundException {
for (Path file : inFiles) {
if (Files.isDirectory(file)) {
String filename = base + file.getFileName().toString();
zip(getDirectoryFiles(file), filename + SEP, zout);
} else {
writeZipEntry(zout, file, base);
}
}
}
/**
* Extracts all files of a given zip archive to the parent folder of the
* archive.
*
* @param zipfileName
* archive to be extracted
* @throws FileNotFoundException
* @throws IOException
*/
public static void unzip(String zipfileName) throws FileNotFoundException,
IOException {
Path zipFile = Paths.get(zipfileName);
Path destinationDir = zipFile.getParent();
unzip(zipFile, destinationDir);
}
private static void printUsage() {
System.out.println("usage:");
System.out.println("\tjava ZipCompression -x <zipfile>");
System.out.println("\tjava ZipCompression -a <directory>");
}
private static Set<Path> getDirectoryFiles(Path dir) {
Set<Path> dirFiles = new HashSet<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path file : stream) {
dirFiles.add(file);
}
} catch (IOException | DirectoryIteratorException e) {
e.printStackTrace();
}
return dirFiles;
}
private static void writeZipEntry(ZipOutputStream out, Path inFile,
String base) throws IOException, FileNotFoundException {
System.out.println("write zip entry " + inFile);
try (FileInputStream in = new FileInputStream(inFile.toString())) {
out.putNextEntry(new ZipEntry(base
+ inFile.getFileName().toString()));
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.closeEntry();
}
}
private static void extractEntry(Path destinationDir, ZipInputStream zin,
ZipEntry entry) throws IOException, FileNotFoundException {
Path currentFile = Paths
.get(destinationDir.toString(), entry.getName());
System.out.println("extracting file " + currentFile);
Files.createDirectories(currentFile.getParent());
try (FileOutputStream out = new FileOutputStream(currentFile.toString())) {
byte[] buf = new byte[1024];
int len;
while ((len = zin.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
zin.closeEntry();
}
}
Edit: Slight changes to the code: Program keeps directory structure.