/// <summary> /// Open an new ZipStream. Each ZipStream gets its own zzipDir to allow correct multithreaded reading of files. /// These handles come out of a pool managed by zipFile so tons of extras are not created. /// </summary> /// <remarks> /// This is based on: /// https://bitbucket.org/sinbad/ogre/pull-request/63/made-each-zip-file-stream-have-its-own-zip/diff /// http://zziplib.sourceforge.net/changes.html under 2005-12-11, the zip file is opened and read with only one filehandle for /// multiple threads that share the same "dir" handle. Look for ->currentfp. To get around this we will just open a new zzipDir /// for each file. This uses the extern functions in ZipFile to do this, they are internal. /// </remarks> /// <param name="zipFile">The name of the zip file to load.</param> /// <param name="fileName">The name of the file to load.</param> internal unsafe ZipStream(PooledZzipDir zzipDir, String fileName) { this.zzipDir = zzipDir; //Get uncompressed size ZZipStat zstat = new ZZipStat(); ZipFile.ZipFile_DirStat(zzipDir.Ptr, fileName, &zstat, (int)ZZipFlags.ZZIP_CASELESS); uncompressedSize = zstat.UncompressedSize; //Open file zzipFile = ZipFile.ZipFile_OpenFile(zzipDir.Ptr, fileName, ZZipFlags.ZZIP_ONLYZIP | ZZipFlags.ZZIP_CASELESS); if (zzipFile == IntPtr.Zero) { //Be sure to return the directory handle zzipDir.finished(); throw new ZipIOException("Cannot open file"); } }
private unsafe void commonLoad() { pooledZzipDirHandles = new LifecycleObjectPool <PooledZzipDir>(() => new PooledZzipDir(file), dir => dir.Dispose()); pooledZzipDirHandles.MaxPoolSize = 3; PooledZzipDir zzipDir = pooledZzipDirHandles.getPooledObject(); HashSet <String> foundDirectories = new HashSet <string>(); //Read the directories and files out of the zip file ZZipStat zzipEntry = new ZZipStat(); while (ZipFile_Read(zzipDir.Ptr, &zzipEntry)) { String entryName = zzipEntry.Name; if (fileFilter == null || entryName.StartsWith(fileFilter)) { ZipFileInfo fileInfo = new ZipFileInfo(entryName, zzipEntry.CompressedSize, zzipEntry.UncompressedSize); //Make sure we don't end with a / if (fileInfo.IsDirectory) { if (!foundDirectories.Contains(fileInfo.FullName)) { directories.Add(fileInfo); foundDirectories.Add(fileInfo.FullName); } } else { files.Add(fileInfo); } addParentDirectories(foundDirectories, fileInfo); } } zzipDir.finished(); }