Esempio n. 1
0
        private static void AddFileToZip(
            string fileName, 
            string relativeDir,
            bool keepDirectoryInfo,
            FileStream outputStream,
            BinaryWriter outputWriter,
            BinaryWriter centralDirWriter)
        {
            fileName = Path.GetFullPath(fileName);

            if (!File.Exists(fileName) && !Directory.Exists(fileName))
                throw new FileNotFoundException(fileName);

            bool isDir = Directory.Exists(fileName);

            int uncompressedSize = 0;
            int compressedSize = 0;
            UInt32 crc32 = 0;
            int relativePositionOfThisHeader = 0;

            if (isDir)
            {
                // Write the file header
                AppendFileHeader(outputWriter, fileName, 0, 0, 0, relativeDir, keepDirectoryInfo);
            }
            else
            {
                byte[] inputReadBuffer = null;
                using (MemoryStream compressedStream = new MemoryStream())
                {
                    FileIOPermission readPerm = new FileIOPermission(FileIOPermissionAccess.Read, fileName);
                    readPerm.Demand();

                    using (FileStream inputStream = new FileStream(fileName, FileMode.Open))
                    {
                        uncompressedSize = (int)inputStream.Length;

                        // Calculate the CRC32
                        CRC32 crc = new CRC32();
                        crc32 = crc.GetCrc32(inputStream);

                        inputStream.Seek(0, SeekOrigin.Begin);

                        inputReadBuffer = new byte[uncompressedSize];

                        // Compress the individual file into a temporary stream
                        using (DeflateStream deflateStream = new DeflateStream(compressedStream, CompressionMode.Compress, true))
                        {
                            int bytesRead = inputStream.Read(inputReadBuffer, 0, inputReadBuffer.Length);
                            Debug.Assert(bytesRead == uncompressedSize);

                            deflateStream.Write(inputReadBuffer, 0, inputReadBuffer.Length);
                            deflateStream.Flush();
                        }
                    }

                    compressedStream.Flush();

                    compressedStream.Seek(0, SeekOrigin.Begin);
                    compressedSize = (int)compressedStream.Length;

                    relativePositionOfThisHeader = (int)outputStream.Position;

                    // Write the file header
                    AppendFileHeader(outputWriter, fileName, compressedSize, uncompressedSize, crc32, relativeDir, keepDirectoryInfo);

                    // Write the compressed data
                    byte[] buffer = new byte[compressedStream.Length];
                    compressedStream.Read(buffer, 0, buffer.Length);

            #if DEBUG
                    using (MemoryStream memStr = new MemoryStream())
                    {
                        memStr.Write(buffer, 0, buffer.Length);
                        memStr.Flush();
                        memStr.Seek(0, SeekOrigin.Begin);

                        byte[] allContent = null;

                        using (DeflateStream testUnZip = new DeflateStream(memStr, CompressionMode.Decompress))
                        using (BinaryReader testRdr = new BinaryReader(testUnZip))
                        {

                            allContent = testRdr.ReadBytes(uncompressedSize);
                            Debug.Assert(allContent.Length == uncompressedSize);
                        }

                        for(int i = 0; i < uncompressedSize; i++)
                            Debug.Assert(allContent[i] == inputReadBuffer[i]);
                    }
            #endif

                    // Add the compressed data to the output stream
                    outputStream.Write(buffer, 0, buffer.Length);
                }
            }

            // Write the central dir header
            AppendCentralDirHeader(centralDirWriter, fileName, compressedSize, uncompressedSize, crc32, relativePositionOfThisHeader, relativeDir, keepDirectoryInfo);
        }