package org.amse.ys.zip; import java.io.*; import java.util.*; public final class ZipFile { public static interface InputStreamHolder { InputStream getInputStream() throws IOException; boolean getZipflag(); } private static final class FileInputStreamHolder implements InputStreamHolder { private final String myFilePath; private boolean zipfileflag=false; FileInputStreamHolder(String filePath) { myFilePath = filePath; String tmp=filePath.toLowerCase(); System.out.println("---"+filePath); if(tmp.indexOf(".zip")!=-1){ zipfileflag=true; } } public boolean getZipflag(){ return zipfileflag; } public InputStream getInputStream() throws IOException { return new FileInputStream(myFilePath); } } private final InputStreamHolder myStreamHolder; private final LinkedHashMap<String,LocalFileHeader> myFileHeaders = new LinkedHashMap<String,LocalFileHeader>() { @Override public LocalFileHeader get(Object key) { return super.get(((String)key).toLowerCase()); } @Override public LocalFileHeader put(String key, LocalFileHeader value) { return super.put(key.toLowerCase(), value); } }; private boolean myAllFilesAreRead; public ZipFile(String filePath) { this(new FileInputStreamHolder(filePath)); } public ZipFile(InputStreamHolder streamHolder) { myStreamHolder = streamHolder; } public Collection<LocalFileHeader> headers() { try { readAllHeaders(); } catch (IOException e) { } return myFileHeaders.values(); } private boolean readFileHeader(MyBufferedInputStream baseStream, String fileToFind) throws IOException { LocalFileHeader header = new LocalFileHeader(); header.readFrom(baseStream,myStreamHolder.getZipflag()); if (header.Signature != LocalFileHeader.FILE_HEADER_SIGNATURE) { return false; } if (header.FileName != null) { myFileHeaders.put(header.FileName, header); if (header.FileName.equalsIgnoreCase(fileToFind)) { return true; } } if ((header.Flags & 0x08) == 0) { baseStream.skip(header.CompressedSize); } else { findAndReadDescriptor(baseStream, header); } return false; } private void readAllHeaders() throws IOException { if (myAllFilesAreRead) { return; } myAllFilesAreRead = true; // if() MyBufferedInputStream baseStream = getBaseStream(); baseStream.setPosition(0); myFileHeaders.clear(); try { while (true) { readFileHeader(baseStream, null); } } finally { storeBaseStream(baseStream); } } /** * Finds descriptor of the last header and installs sizes of files */ private void findAndReadDescriptor(MyBufferedInputStream baseStream, LocalFileHeader header) throws IOException { Decompressor decompressor = Decompressor.init(baseStream, header); int uncompressedSize = 0; while (true) { int blockSize = decompressor.read(null, 0, 2048); if (blockSize <= 0) { break; } uncompressedSize += blockSize; } header.UncompressedSize = uncompressedSize; } private final Queue<MyBufferedInputStream> myStoredStreams = new LinkedList<MyBufferedInputStream>(); synchronized void storeBaseStream(MyBufferedInputStream baseStream) { myStoredStreams.add(baseStream); } synchronized MyBufferedInputStream getBaseStream() throws IOException { MyBufferedInputStream baseStream = myStoredStreams.poll(); return (baseStream != null) ? baseStream : new MyBufferedInputStream(myStreamHolder); } private ZipInputStream createZipInputStream(LocalFileHeader header) throws IOException { return new ZipInputStream(this, header); } public int getEntrySize(String entryName) throws IOException { return getHeader(entryName).UncompressedSize; } public InputStream getInputStream(String entryName) throws IOException { return createZipInputStream(getHeader(entryName)); } public LocalFileHeader getHeader(String entryName) throws IOException { if (!myFileHeaders.isEmpty()) { LocalFileHeader header = myFileHeaders.get(entryName); if (header != null) { return header; } if (myAllFilesAreRead) { throw new ZipException("Entry " + entryName + " is not found"); } } // ready to read file header MyBufferedInputStream baseStream = getBaseStream(); baseStream.setPosition(0); try { while (!readFileHeader(baseStream, entryName)) { } LocalFileHeader header = myFileHeaders.get(entryName); if (header != null) { return header; } } finally { storeBaseStream(baseStream); } throw new ZipException("Entry " + entryName + " is not found"); } }