public void GenerateArchive(byte[] header, byte[] trailer, string outputPath) { var headerLength = header.Length; using (var memory = new FileStream(outputPath, FileMode.Create)) { using (var writer = new BinaryWriter(memory)) { writer.Write(header); foreach (var file in _files) { file.LocalHeaderOffset = (uint)(writer.BaseStream.Length - headerLength); writer.Write(file.LocalFileHeader.FileHeader); writer.Write(file.File.Span); } var localFilesSize = writer.BaseStream.Length - headerLength; foreach (var file in _files) { writer.Write(file.CentralDircetoryFileHeader.FileHeader); } var centralDirSize = writer.BaseStream.Length - localFilesSize - headerLength; var eocdRecord = new EndOfCentralDirectoryRecord((uint)localFilesSize, (uint)centralDirSize, (ushort)_files.Count, _comment); writer.Write(eocdRecord.FileHeader); writer.Write(trailer); } } }
public CentralDirectory(Stream reader) { _stream = reader; var sig = EndOfCentralDirectoryRecord.HeaderSignature; _stream.Seek(-1024, SeekOrigin.End); var found = false; var counter = 0; int currentByte; while (!found && (currentByte = _stream.ReadByte()) != -1) { if (sig[counter] == (byte)currentByte) { counter++; } else { counter = 0; } if (counter == sig.Length) { found = true; } } if (found) { _stream.Seek(-4, SeekOrigin.Current); Span <byte> buffer = stackalloc byte[(int)(_stream.Length - _stream.Position)]; _stream.Read(buffer); _eocdHeader = new EndOfCentralDirectoryRecord(buffer); _stream.Seek(_eocdHeader.CentralDirectoryOffset + 516, SeekOrigin.Begin); var cdBuffer = new byte[_eocdHeader.CentralDirectorySize].AsSpan(); _stream.Read(cdBuffer); _cdHeaders = new List <CentralDirectoryFileHeader>(_eocdHeader.TotalEntries); var offset = 0; while (_cdHeaders.Count < _eocdHeader.TotalEntries) { var header = new CentralDirectoryFileHeader(cdBuffer.Slice(offset)); offset += header.FileHeader.Length; _cdHeaders.Add(header); } } else { throw new ArgumentException("End of Directory Header could not be found!"); } }