So, I want to say that I have a zip file containing several files and directories that can contain more files. What I'm looking for is a convenient way to extract this tree structure into an object graph, whether it be a TreeMap or not. So, for example: HashMap: {'root', 'HashMap: {' file1.png '=> byte [] content}}
As I have answered several times on another question, the Java API does not have a single βtree-likeβ data structure (tree-based interface), since each use requires a different function. For example, your proposed HashMap tree is not implemented in type save mode - you need wrapper objects somewhere.
I donβt know if there is a tree view of the zip file somewhere to (not) answer your question, but creating it is not so difficult as soon as you define the desired tree interface.
So, here is an example class that does what you want (from what I understand).
import java.io.*; import java.util.*; import java.util.zip.*; public class ZipNode { private ZipNode parent; private Map<String,ZipNode> children; private boolean directory; private ZipEntry entry; private ZipFile file; private ZipNode(ZipFile f, ZipEntry entry) { this.file = f; this.entry = entry; if(entry == null || entry.isDirectory()) { directory = true; children = new LinkedHashMap<String, ZipNode>(); } else { directory = false; children = Collections.emptyMap(); } } public String getName() { if(entry == null) return "/"; String longName = entry.getName(); return longName.substring(longName.lastIndexOf('/', longName.length()-2)+1); } public ZipEntry getEntry() { return entry; } public ZipFile getZipFile() { return file; } public boolean isDirectory() { return directory; } public ZipNode getParent() { return parent; } public Map<String,ZipNode> getChildren() { return Collections.unmodifiableMap(children); } public InputStream openStream() throws IOException { return file.getInputStream(entry); } public String toString() { return "ZipNode [" + entry.getName() + "] in [" + file.getName() + "]"; } public static ZipNode fromZipFile(ZipFile zf) { return new ZipFileReader(zf).process(); } private static class ZipFileReader { private ZipFile file; private Map<String, ZipNode> collected; private ZipNode root; ZipFileReader(ZipFile f) { this.file = f; this.collected = new HashMap<String, ZipNode>(); collected.put("", root); root = new ZipNode(f, null); } ZipNode process() { for(Enumeration<? extends ZipEntry> entries = file.entries(); entries.hasMoreElements(); ) { this.addEntry(entries.nextElement()); } return root; } private ZipNode addEntry(ZipEntry entry) { String name = entry.getName(); ZipNode node = collected.get(name); if(node != null) {
This has the main method for using the test, its output for one of my jar files:
/ ββ META-INF/ β β°β MANIFEST.MF β°β de/ β°β fencing_game/ ββ start/ β ββ Runner.class β ββ ServerMain$1.class β ββ ServerMain.class β β°β package-info.class ββ log/ β ββ Log$1.class β ββ Log.class β ββ LogImplClient.class β ββ Loggable.class β β°β package-info.class β°β tools/ β°β load/ ββ ServiceTools$1.class ββ ServiceTools$2.class ββ ServiceTools$3.class ββ ServiceTools.class β°β TwoParentClassLoader.class
(You only need a Unicode-compatible terminal and Unicode encoding for System.out.)