Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@edermag
Last active December 22, 2015 07:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edermag/6435674 to your computer and use it in GitHub Desktop.
Save edermag/6435674 to your computer and use it in GitHub Desktop.
Programa Java extrai um diretório contido em arquivo Zip
import static java.lang.System.currentTimeMillis;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* This class uses the Zip API from <code>java.util.zip</code>, to extract a content of directory.
* Inside a directory contains one or many files and sub-directories.
*
* <p>Example:</p>
* <blockquote><pre>
* ExtractZipDir.extract("/home/user/my.zip", "xdir");
* </pre></blockquote>
*
* <p>Any error during the extract will be throws as a {@code}RuntimeException.<p>
*
* @see java.util.zip
*
* @author eder.magalhaes
*/
public class ExtractZipDir {
public static void main(String[] args ) {
if (args.length < 2) {
System.out.println("Sorry... I need to know the zip name and the directory to extract.");
System.out.println("See how call this program:");
System.out.println("\tExtractZipDir my.zip xdir");
return;
}
String zipName = args[0];
String dirName = args[1];
extract(zipName, dirName);
}
static void extract(String zipName, String dirName) {
long before = currentTimeMillis();
try (ZipFile zip = new ZipFile(new File(zipName))) {
ZipContent zContent = new ZipContent(zip);
int files = zContent.extract(dirName);
System.out.printf("Extract %s files (in %sms)", files, currentTimeMillis() - before);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Encapsulate the zip content, in a <code>Map</code> collection.
*/
private static class ZipContent {
private final ZipFile zip;
private Map<String, List<ZipEntry>> content = new HashMap<>();
private int count;
private static final String SEPARATOR = "/";
private static final String ROOT_DIRECTORY = ".";
private static final int BUFFER = 2048;
private ZipContent (ZipFile zipFile) {
zip = zipFile;
organizeEntries(zip.entries());
}
private void organizeEntries(Enumeration<? extends ZipEntry> entries) {
putRootDir();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
putEntry(entry);
}
}
private void putEntry(ZipEntry entry) {
String path = extractDirNameFromEntry(entry);
List<ZipEntry> entries = content.get(path);
if (entries == null) {
content.put(path, new LinkedList<ZipEntry>());
} else {
entries.add(entry);
}
}
private void putRootDir() {
content.put(ROOT_DIRECTORY, new LinkedList<ZipEntry>());
}
private List<ZipEntry> listContent(String folder) {
return content.get(folder);
}
private boolean hasDirectory(String folder) {
return content.keySet().contains(folder);
}
private Queue<String> getAllDirectoriesFromParent(String dir) {
Queue<String> q = new LinkedList<>();
for (String d: content.keySet()) {
if (d.contains(dir) && !d.equals(dir))
q.add(d);
}
q.add(dir);
return q;
}
private int extract(String dir) {
if (!dir.equals(ROOT_DIRECTORY)) {
if (!dir.endsWith(SEPARATOR)) {
dir = dir.concat(SEPARATOR);
}
if (!hasDirectory(dir)) {
throw new RuntimeException("Directory not found!");
}
}
count = 0;
Queue<String> dirs = getAllDirectoriesFromParent(dir);
while (!dirs.isEmpty()) {
String path = dirs.poll();
List<ZipEntry> entries = listContent(path);
File parent = new File(path);
parent.mkdirs();
for (ZipEntry entry: entries) {
extract(parent, entry);
count++;
}
}
return count;
}
private void extract(File path, ZipEntry entry) {
String fileName = extractFilenameFromEntry(entry);
File destFile = new File(path, fileName);
try (BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER)) {
int currentByte;
byte data[] = new byte[BUFFER];
while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
} catch (IOException e) {
throw new RuntimeException("Not possible to extract!\n" + e.getMessage(), e);
}
}
private static String extractDirNameFromEntry(ZipEntry entry) {
String name = entry.getName();
if (name.lastIndexOf(SEPARATOR) != -1) {
return name.substring(0, name.lastIndexOf(SEPARATOR)+1);
}
return ROOT_DIRECTORY;
}
private static String extractFilenameFromEntry(ZipEntry entry) {
String name = entry.getName();
if (name.lastIndexOf(SEPARATOR) == -1) {
return name;
}
return name.substring(name.lastIndexOf(SEPARATOR)+1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment