public static void findZip(String zipName, InputStream zipInput, FileFilter searchFilter, List<String> results)
			throws IOException {
		ZipInputStream zin = new ZipInputStream(zipInput);
		while (true) {
			final ZipEntry en;
			try {
				en = zin.getNextEntry();
			} catch (IOException | IllegalArgumentException e) {
				throw new IOException("While handling file " + zipName, e);
			}
			if(en == null) {
				break;
			}
			if (searchFilter.accept(new File(en.getName()))) {
				results.add(zipName + ZIP_DELIMITER + en);
			}
			if (ZipUtils.isZip(en.getName())) {
				findZip(zipName + ZIP_DELIMITER + en, zin, searchFilter, results);
			}
		}
	}
public static void findZip ( String zipName , InputStream zipInput , FileFilter searchFilter , List < String > results ) throws IOException { ZipInputStream zin = new ZipInputStream ( zipInput ) ; while ( true ) { final ZipEntry en ; try { en = zin . getNextEntry ( ) ; } catch ( IOException | IllegalArgumentException e ) { throw new IOException ( "While handling file " + zipName , e ) ; } if ( en == null ) { break ; } if ( searchFilter . accept ( new File ( en . getName ( ) ) ) ) { results . add ( zipName + ZIP_DELIMITER + en ) ; } if ( ZipUtils . isZip ( en . getName ( ) ) ) { findZip ( zipName + ZIP_DELIMITER + en , zin , searchFilter , results ) ; } } }
Looks in the ZIP file available via zipInput for files matching the provided file-filter,
recursing into sub-ZIP files.

@param zipName Name of the file to read, mainly used for building the resulting pointer into the zip-file
@param zipInput An InputStream which is positioned at the beginning of the zip-file contents
@param searchFilter A {@link FileFilter} which determines if files in the zip-file are matched
@param results A existing list where found matches are added to.

@throws IOException
If the ZIP file cannot be read, e.g. if it is corrupted.