public class ExtractZipDir { public static void main(String[] args ) { if (args.length < 2) { System.out.println("Informe o arquivo zip e a pasta"); 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("Extraiu %s arquivos (e, %sms)", files, currentTimeMillis() - before); } catch (Exception ex) { ex.printStackTrace(); } } 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 e) { String fileName = extractFilenameFromEntry(e); File destFile = new File(path, fileName); try (BufferedInputStream is = new BufferedInputStream(zip.getInputStream(e)); 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("Não foi possível extrair!\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); } } }
Alguns formas de como executar esse programa (Linux / Windows):
$ java ExtractZipDir /home/user/meu.zip dir $ java C:\usuario\Documents\meu.zip dir
Compartilhei esse código no github.
@edermag
No comments:
Post a Comment