Beispiel #1
0
 private static bool AddDirectory(ZipArchive zipArchive, DirectoryInfo rootDirectoryInfo, string currentDirectory)
 {
     string fullDirectoryPath = Path.Combine(rootDirectoryInfo.FullName, currentDirectory);
     DirectoryInfo directoryInfo = new DirectoryInfo(fullDirectoryPath);
     FileSystemInfo[] fileSystemInfos = directoryInfo.GetFileSystemInfos();
     foreach (FileSystemInfo fileSystemInfo in fileSystemInfos)
     {
         if (fileSystemInfo is FileInfo)
         {
             FileInfo childFileInfo = fileSystemInfo as FileInfo;
             string fileName = Path.Combine(currentDirectory, childFileInfo.Name);
             FileStream fileData = new FileStream(childFileInfo.FullName, FileMode.Open);
             ZipFileEntry fileEntry = new ZipFileEntry(fileName, fileData);
             zipArchive.Entries.Add(fileEntry);
         }
         else if (fileSystemInfo is DirectoryInfo)
         {
             DirectoryInfo childDirectoryInfo = fileSystemInfo as DirectoryInfo;
             string directoryName = Path.Combine(currentDirectory, childDirectoryInfo.Name);
             bool directoryHasEntries = AddDirectory(zipArchive, rootDirectoryInfo, directoryName);
             if (!directoryHasEntries)
             {
                 ZipDirectoryEntry directoryEntry = new ZipDirectoryEntry(directoryName);
                 zipArchive.Entries.Add(directoryEntry);
             }
         }
     }
     return (fileSystemInfos.Length != 0);
 }
Beispiel #2
0
        public void ReadFrom(Stream zipStream)
        {
            while (zipStream.Position < zipStream.Length)
            {
                BinaryReader reader = new BinaryReader(zipStream, Encoding.ASCII);
                uint localFileHeaderSignature = reader.ReadUInt32();
                if (localFileHeaderSignature != LOCAL_FILE_HEADER_SIGNATURE)
                {
                    // Local file entries are finished, next records are central directory records
                    break;
                }
                ushort versionNeededToExtract = reader.ReadUInt16();
                ushort generalPurposeBitFlag = reader.ReadUInt16();
                ushort compressionMethod = reader.ReadUInt16();
                if (compressionMethod != COMPRESSION_DEFLATE && compressionMethod != COMPRESSION_STORE)
                {
                    throw new NotSupportedException(ARCHIVE_FORMAT_NOT_SUPPORTED_STRING);
                }
                uint lastModifiedDateTime = reader.ReadUInt32();
                uint crc32 = reader.ReadUInt32();
                uint compressedSize = reader.ReadUInt32();
                uint uncompressedSize = reader.ReadUInt32();
                ushort fileNameLength = reader.ReadUInt16();
                ushort extraFieldLength = reader.ReadUInt16();
                if (extraFieldLength != 0)
                {
                    throw new NotSupportedException(ARCHIVE_FORMAT_NOT_SUPPORTED_STRING);
                }

                byte[] fileNameBytes = reader.ReadBytes(fileNameLength);
                Encoding fileNameEncoding;
                if ((generalPurposeBitFlag & UTF8_FILE_NAME_ENCODING_FLAG) != 0)
                {
                    fileNameEncoding = new UTF8Encoding();
                }
                else
                {
                    fileNameEncoding = Encoding.GetEncoding((int)GetOEMCP());
                }
                string fileName = new string(fileNameEncoding.GetChars(fileNameBytes));

                // According to ZIP specification, ZIP archives generally 
                // contain forward slashes so make Windows file name
                fileName = fileName.Replace('/', Path.DirectorySeparatorChar);

                ZipEntry entry = null;
                if (uncompressedSize != 0)
                {
                    byte[] fileData = reader.ReadBytes((int)compressedSize);
                    MemoryStream fileDataStream = new MemoryStream(fileData);
                    ZipFileEntry fileEntry = new ZipFileEntry(fileName, fileDataStream);
                    if (compressionMethod == COMPRESSION_DEFLATE)
                    {
                        fileDataStream.Position = 0;
                        DeflateStream deflateStream = new DeflateStream(fileDataStream, CompressionMode.Decompress);

                        byte[] uncompressedFileData = new byte[uncompressedSize];

                        deflateStream.Read(uncompressedFileData, 0, (int)uncompressedSize);
                        fileEntry.Data = new MemoryStream(uncompressedFileData);
                    }
                    entry = fileEntry;
                }
                else if (fileName.EndsWith(@"\"))
                {
                    entry = new ZipDirectoryEntry(fileName);
                }
                else
                {
                    entry = new ZipFileEntry(fileName, null);
                }
                entry.SetLastModifiedDateTime(lastModifiedDateTime);
                entries.Add(entry);
            }

        }
Beispiel #3
0
        public void WriteTo(Stream zipStream, CompressionMethod compressionMethod, bool encodeFileNamesInUTF8)
        {
            MemoryStream centralDirectory       = new MemoryStream();
            BinaryWriter centralDirectoryWriter = new BinaryWriter(centralDirectory);
            BinaryWriter zipStreamWriter        = new BinaryWriter(zipStream);

            foreach (ZipEntry entry in entries)
            {
                Encoding fileNameEncoding = encodeFileNamesInUTF8
                    ? new UTF8Encoding()
                    : Encoding.GetEncoding((int)GetOEMCP());

                uint   crc32            = 0;
                uint   compressedSize   = 0;
                uint   uncompressedSize = 0;
                string fileName         = null;
                Stream compressedData   = null;

                if (entry is ZipFileEntry)
                {
                    ZipFileEntry fileEntry = entry as ZipFileEntry;
                    fileName = fileEntry.FileName;

                    if (fileEntry.Data != null && fileEntry.Data.Length != 0)
                    {
                        compressedData = fileEntry.Data;
                        if (compressionMethod == CompressionMethod.Deflate)
                        {
                            MemoryStream  compressedStream = new MemoryStream();
                            DeflateStream deflateStream    = new DeflateStream(compressedStream, CompressionMode.Compress, true);
                            WriteStream(fileEntry.Data, deflateStream);
                            deflateStream.Close();
                            compressedData = compressedStream;
                        }
                        crc32            = fileEntry.Crc;
                        compressedSize   = (uint)compressedData.Length;
                        uncompressedSize = (uint)fileEntry.Data.Length;
                    }
                    else
                    {
                        crc32            = 0;
                        compressedSize   = 0;
                        uncompressedSize = 0;
                    }
                }
                else
                {
                    ZipDirectoryEntry directoryEntry = entry as ZipDirectoryEntry;
                    fileName = directoryEntry.DirectoryName;
                }
                // According to ZIP specification, file names should use only forward slashes
                // to be compatible with Unix file systems
                fileName = fileName.Replace(Path.DirectorySeparatorChar, '/');
                if (entry is ZipDirectoryEntry && !fileName.EndsWith("/"))
                {
                    // Directories should contain slash at the end
                    fileName += "/";
                }
                byte[] fileNameBytes = fileNameEncoding.GetBytes(fileName);

                ushort versionNeededToExtract = VERSION_NEEDED_TO_EXTRACT;
                ushort generalPurposeBitFlag  = encodeFileNamesInUTF8 ? UTF8_FILE_NAME_ENCODING_FLAG : (ushort)0;
                uint   lastModifiedDateTime   = entry.GetLastModifiedDateTime();
                ushort fileNameLength         = (ushort)fileNameBytes.Length;
                ushort extraFieldLength       = 0;

                uint localHeaderPosition = (uint)zipStream.Position;
                zipStreamWriter.Write(LOCAL_FILE_HEADER_SIGNATURE);
                zipStreamWriter.Write(versionNeededToExtract);
                zipStreamWriter.Write(generalPurposeBitFlag);
                zipStreamWriter.Write((ushort)compressionMethod);
                zipStreamWriter.Write(lastModifiedDateTime);
                zipStreamWriter.Write(crc32);
                zipStreamWriter.Write(compressedSize);
                zipStreamWriter.Write(uncompressedSize);
                zipStreamWriter.Write(fileNameLength);
                zipStreamWriter.Write(extraFieldLength);
                zipStreamWriter.Write(fileNameBytes, 0, fileNameBytes.Length);

                if (compressedData != null)
                {
                    WriteStream(compressedData, zipStream);
                }

                centralDirectoryWriter.Write(CENTRAL_FILE_HEADER_SIGNATURE);
                centralDirectoryWriter.Write(VERSION_NEEDED_TO_EXTRACT);
                centralDirectoryWriter.Write(VERSION_NEEDED_TO_EXTRACT);
                centralDirectoryWriter.Write(generalPurposeBitFlag);
                centralDirectoryWriter.Write((ushort)compressionMethod);
                centralDirectoryWriter.Write(lastModifiedDateTime);
                centralDirectoryWriter.Write(crc32);
                centralDirectoryWriter.Write(compressedSize);
                centralDirectoryWriter.Write(uncompressedSize);
                centralDirectoryWriter.Write(fileNameLength);
                centralDirectoryWriter.Write(extraFieldLength);
                centralDirectoryWriter.Write((ushort)0);           // file comment length
                centralDirectoryWriter.Write((ushort)0);           // disk number start
                centralDirectoryWriter.Write((ushort)0);           // internal file attributes
                centralDirectoryWriter.Write((uint)0);             // external file attributes
                centralDirectoryWriter.Write(localHeaderPosition); // relative offset of local header
                centralDirectoryWriter.Write(fileNameBytes, 0, fileNameBytes.Length);
            }
            uint centralDirectorySize   = (uint)centralDirectory.Length;
            uint centralDirectoryOffset = (uint)zipStream.Position;

            centralDirectoryWriter.Write(END_OF_CENTRAL_DIR_SIGNATURE);
            centralDirectoryWriter.Write((ushort)0);                    // number of this disk
            centralDirectoryWriter.Write((ushort)0);                    // number of the disk with the start of the central directory
            centralDirectoryWriter.Write((ushort)entries.Count);        // total number of entries in the central directory on this disk
            centralDirectoryWriter.Write((ushort)entries.Count);        // total number of entries in the central directory
            centralDirectoryWriter.Write((uint)centralDirectorySize);   // size of the central directory
            centralDirectoryWriter.Write((uint)centralDirectoryOffset); // offset of start of central directory with respect to the starting disk number
            centralDirectoryWriter.Write((ushort)0);                    // .ZIP file comment length
            WriteStream(centralDirectory, zipStream);
        }
Beispiel #4
0
 public static void CreateFromFile(string sourceFile, Stream outputZipStream)
 {
     if (File.Exists(sourceFile))
     {
         ZipArchive archive = new ZipArchive();
         string fileName = Path.GetFileName(sourceFile);
         Stream fileData = new FileStream(sourceFile, FileMode.Open);
         ZipFileEntry fileEntry = new ZipFileEntry(fileName, fileData);
         archive.Entries.Add(fileEntry);
         archive.WriteTo(outputZipStream);
     }
 }
Beispiel #5
0
        public void ReadFrom(Stream zipStream)
        {
            while (zipStream.Position < zipStream.Length)
            {
                BinaryReader reader = new BinaryReader(zipStream, Encoding.ASCII);
                uint         localFileHeaderSignature = reader.ReadUInt32();
                if (localFileHeaderSignature != LOCAL_FILE_HEADER_SIGNATURE)
                {
                    // Local file entries are finished, next records are central directory records
                    break;
                }
                ushort versionNeededToExtract = reader.ReadUInt16();
                ushort generalPurposeBitFlag  = reader.ReadUInt16();
                ushort compressionMethod      = reader.ReadUInt16();
                if (compressionMethod != COMPRESSION_DEFLATE && compressionMethod != COMPRESSION_STORE)
                {
                    throw new NotSupportedException(ARCHIVE_FORMAT_NOT_SUPPORTED_STRING);
                }
                uint   lastModifiedDateTime = reader.ReadUInt32();
                uint   crc32            = reader.ReadUInt32();
                uint   compressedSize   = reader.ReadUInt32();
                uint   uncompressedSize = reader.ReadUInt32();
                ushort fileNameLength   = reader.ReadUInt16();
                ushort extraFieldLength = reader.ReadUInt16();
                if (extraFieldLength != 0)
                {
                    throw new NotSupportedException(ARCHIVE_FORMAT_NOT_SUPPORTED_STRING);
                }

                byte[]   fileNameBytes = reader.ReadBytes(fileNameLength);
                Encoding fileNameEncoding;
                if ((generalPurposeBitFlag & UTF8_FILE_NAME_ENCODING_FLAG) != 0)
                {
                    fileNameEncoding = new UTF8Encoding();
                }
                else
                {
                    fileNameEncoding = Encoding.GetEncoding((int)GetOEMCP());
                }
                string fileName = new string(fileNameEncoding.GetChars(fileNameBytes));

                // According to ZIP specification, ZIP archives generally
                // contain forward slashes so make Windows file name
                fileName = fileName.Replace('/', Path.DirectorySeparatorChar);

                ZipEntry entry = null;
                if (uncompressedSize != 0)
                {
                    byte[]       fileData       = reader.ReadBytes((int)compressedSize);
                    MemoryStream fileDataStream = new MemoryStream(fileData);
                    ZipFileEntry fileEntry      = new ZipFileEntry(fileName, fileDataStream);
                    if (compressionMethod == COMPRESSION_DEFLATE)
                    {
                        fileDataStream.Position = 0;
                        DeflateStream deflateStream = new DeflateStream(fileDataStream, CompressionMode.Decompress);

                        byte[] uncompressedFileData = new byte[uncompressedSize];

                        deflateStream.Read(uncompressedFileData, 0, (int)uncompressedSize);
                        fileEntry.Data = new MemoryStream(uncompressedFileData);
                    }
                    entry = fileEntry;
                }
                else if (fileName.EndsWith(@"\"))
                {
                    entry = new ZipDirectoryEntry(fileName);
                }
                else
                {
                    entry = new ZipFileEntry(fileName, null);
                }
                entry.SetLastModifiedDateTime(lastModifiedDateTime);
                entries.Add(entry);
            }
        }