public ZipEndOfCentralDirectory(Stream stream) { BinaryReader reader = new BinaryReader(stream); // Start searching for the Zip End of Central Directory signature from the end // of the file backwards (towards the beginning of the file). This allows us to // find Zip archives with extra data appended to the archive (for whatever reason // someone might want to do that). long offset = stream.Length - ZipEndOfCentralDirectory.EOCD_RECORD_FIXEDSIZE; for (; offset >= 0; --offset) { stream.Seek(offset, SeekOrigin.Begin); uint sig = reader.ReadUInt32(); if (sig == ZipEndOfCentralDirectory.EOCDSIG) { break; } } if (offset < 0) { throw new InvalidDataException("Failed to find end of central directory record."); } stream.Seek(offset, SeekOrigin.Begin); this.Read(stream); // If the offset to the central directory is DWORD_MAX then this must be a 64-bit // archive. if (this.dirOffset == (long)UInt32.MaxValue) { string saveComment = this.comment; stream.Seek(offset - Zip64EndOfCentralDirectoryLocator.EOCDL64_SIZE, SeekOrigin.Begin); Zip64EndOfCentralDirectoryLocator eocdl = new Zip64EndOfCentralDirectoryLocator(stream); if (eocdl.dirStartDiskNumber == eocdl.totalDisks - 1) { // ZIP64 eocd is entirely in current stream. stream.Seek(eocdl.dirOffset, SeekOrigin.Begin); this.Read64(stream); } else { // TODO: handle EOCD64 spanning archives! throw new NotImplementedException("Zip implementation does not handle end of central directory record that spans archives."); } this.comment = saveComment; } // Read the central directory for the archive. stream.Seek(this.dirOffset, SeekOrigin.Begin); while (this.headers.Count < this.totalEntries) { ZipFileHeader header = new ZipFileHeader(true); if (!header.Read(stream)) { throw new InvalidDataException("Missing or invalid central directory file header"); } this.headers.Add(header); if (this.headers.Count < this.totalEntries && stream.Position == stream.Length) { //streamContext.CloseArchiveReadStream(this.currentArchiveNumber, String.Empty, archiveStream); //this.currentArchiveNumber++; //archiveStream = streamContext.OpenArchiveReadStream(this.currentArchiveNumber, String.Empty, this); //if (archiveStream == null) //{ // this.currentArchiveNumber = 0; // archiveStream = streamContext.OpenArchiveReadStream(this.currentArchiveNumber, String.Empty, this); //} } } }
public IList <ZipFileHeader> GetCentralDirectory(Stream streamContext) { Stream archiveStream = null; //this.currentArchiveNumber = 0; try { List <ZipFileHeader> headers = new List <ZipFileHeader>(); archiveStream = streamContext; //archiveStream = this.OpenArchive(streamContext, 0); ZipEndOfCentralDirectory eocd = this.GetEOCD(archiveStream); if (eocd == null) { return(null); } else if (eocd.totalEntries == 0) { return(headers); } headers.Capacity = (int)eocd.totalEntries; if (eocd.dirOffset > archiveStream.Length - ZipFileHeader.CFH_FIXEDSIZE) { //streamContext.CloseArchiveReadStream(this.currentArchiveNumber, String.Empty, archiveStream); archiveStream = null; } else { archiveStream.Seek(eocd.dirOffset, SeekOrigin.Begin); uint sig = new BinaryReader(archiveStream).ReadUInt32(); if (sig != ZipFileHeader.CFHSIG) { //streamContext.CloseArchiveReadStream(this.currentArchiveNumber, String.Empty, archiveStream); archiveStream = null; } } if (archiveStream == null) { //this.currentArchiveNumber = (short)(eocd.dirStartDiskNumber + 1); //archiveStream = streamContext.OpenArchiveReadStream(this.currentArchiveNumber, String.Empty, this); if (archiveStream == null) { return(null); } } archiveStream.Seek(eocd.dirOffset, SeekOrigin.Begin); while (headers.Count < eocd.totalEntries) { ZipFileHeader header = new ZipFileHeader(true); if (!header.Read(archiveStream)) { throw new InvalidDataException("Missing or invalid central directory file header"); } headers.Add(header); if (headers.Count < eocd.totalEntries && archiveStream.Position == archiveStream.Length) { //streamContext.CloseArchiveReadStream(this.currentArchiveNumber, String.Empty, archiveStream); //this.currentArchiveNumber++; //archiveStream = streamContext.OpenArchiveReadStream(this.currentArchiveNumber, String.Empty, this); //if (archiveStream == null) //{ // this.currentArchiveNumber = 0; // archiveStream = streamContext.OpenArchiveReadStream(this.currentArchiveNumber, String.Empty, this); //} } } return(headers); } finally { //if (archiveStream != null) //{ // streamContext.CloseArchiveReadStream(this.currentArchiveNumber, String.Empty, archiveStream); //} } }