Пример #1
0
        public void ExtractEntry(Entry entry, Stream outputStream, ZipProgressHandler progressHandler = null)
        {
            if (entry.Offset >= _Stream.Length)
            {
                throw new Exception("Invalid ZIP entry offset");
            }

            _Stream.Seek(entry.Offset, SeekOrigin.Begin);

            byte[] buffer = new byte[1024 * 1024];

            _Stream.Read(buffer, 0, 30);
            ushort fileNameLength   = BitConverter.ToUInt16(buffer, 26);
            ushort extraFieldLength = BitConverter.ToUInt16(buffer, 28);

            _Stream.Seek(entry.Offset + 30 + fileNameLength + extraFieldLength, SeekOrigin.Begin);

            Stream dataStream;

            switch (entry.CompressionMethod)
            {
            case 0:
                dataStream = _Stream;
                break;

            case 8:
                dataStream = new System.IO.Compression.DeflateStream(_Stream, System.IO.Compression.CompressionMode.Decompress, true);
                break;

            default:
                throw new Exception("Unsupported ZIP compression method: " + entry.CompressionMethod + " for " + entry.FileName);
            }

            uint done = 0;

            while (done < entry.UncompressedSize)
            {
                int todo = (int)Math.Min(entry.UncompressedSize - done, (uint)buffer.Length);
                if (dataStream.Read(buffer, 0, todo) != todo)
                {
                    throw new Exception("Cannot read data from ZIP stream for " + entry.FileName);
                }

                outputStream.Write(buffer, 0, todo);

                done += (uint)todo;

                if (progressHandler != null)
                {
                    progressHandler(done, entry.UncompressedSize);
                }
            }

            if (dataStream != _Stream)
            {
                dataStream.Dispose();
            }
        }
Пример #2
0
 /// <summary>
 /// 压缩多层目录
 /// </summary>
 /// <param name="strDirectory">The directory.</param>
 /// <param name="zipedFile">The ziped file.</param>
 public static void ZipFileDirectory(string strDirectory, string zipedFile, ZipProgressHandler progressHandler = null, ZipCompleteHandler completeHandler = null)
 {
     using (System.IO.FileStream ZipFile = System.IO.File.Create(zipedFile))
     {
         using (ZipOutputStream s = new ZipOutputStream(ZipFile))
         {
             ZipSetp(strDirectory, s, "", progressHandler, completeHandler);
             if (completeHandler != null)
             {
                 completeHandler();
             }
         }
     }
 }
Пример #3
0
        public void ExtractEntry(Entry entry, Stream outputStream, ZipProgressHandler progressHandler = null)
        {
            if (entry.Offset >= _Stream.Length)
                throw new Exception("Invalid ZIP entry offset");

            _Stream.Seek(entry.Offset, SeekOrigin.Begin);

            byte[] buffer = new byte[1024 * 1024];

            _Stream.Read(buffer, 0, 30);
            ushort fileNameLength = BitConverter.ToUInt16(buffer, 26);
            ushort extraFieldLength = BitConverter.ToUInt16(buffer, 28);

            _Stream.Seek(entry.Offset + 30 + fileNameLength + extraFieldLength, SeekOrigin.Begin);

            Stream dataStream;

            switch (entry.CompressionMethod)
            {
                case 0:
                    dataStream = _Stream;
                    break;
                case 8:
                    dataStream = new System.IO.Compression.DeflateStream(_Stream, System.IO.Compression.CompressionMode.Decompress, true);
                    break;
                default:
                    throw new Exception("Unsupported ZIP compression method: " + entry.CompressionMethod + " for " + entry.FileName);
            }

            uint done = 0;
            while (done < entry.UncompressedSize)
            {
                int todo = (int)Math.Min(entry.UncompressedSize - done, (uint)buffer.Length);
                if (dataStream.Read(buffer, 0, todo) != todo)
                    throw new Exception("Cannot read data from ZIP stream for " + entry.FileName);

                outputStream.Write(buffer, 0, todo);

                done += (uint)todo;

                if (progressHandler != null)
                    progressHandler(done, entry.UncompressedSize);
            }

            if (dataStream != _Stream)
                dataStream.Dispose();
        }
Пример #4
0
    /// <summary>
    /// 递归遍历目录
    /// </summary>
    /// <param name="strDirectory">The directory.</param>
    /// <param name="s">The ZipOutputStream Object.</param>
    /// <param name="parentPath">The parent path.</param>
    private static void ZipSetp(string strDirectory, ZipOutputStream s, string parentPath, ZipProgressHandler progressHandler = null, ZipCompleteHandler completeHandler = null)
    {
        if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar)
        {
            strDirectory += Path.DirectorySeparatorChar;
        }

        string[] filenames = Directory.GetFileSystemEntries(strDirectory);
        int      i         = 0;
        int      count     = filenames.Length;

        foreach (string file in filenames) // 遍历所有的文件和目录
        {
            if (Directory.Exists(file))    // 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
            {
                string pPath = parentPath;
                pPath += file.Substring(file.LastIndexOf("\\") + 1);
                pPath += "\\";
                ZipSetp(file, s, pPath, progressHandler, completeHandler);
            }

            else // 否则直接压缩文件
            {
                //打开压缩文件
                using (FileStream fs = File.OpenRead(file))
                {
                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);

                    string   fileName = parentPath + file.Substring(file.LastIndexOf("\\") + 1);
                    ZipEntry entry    = new ZipEntry(fileName);

                    entry.DateTime = DateTime.Now;
                    entry.Size     = fs.Length;

                    fs.Close();
                    i++;

                    if (progressHandler != null)
                    {
                        progressHandler(fileName, i, count);
                    }
                    s.PutNextEntry(entry);

                    s.Write(buffer, 0, buffer.Length);
                }
            }
        }
    }
Пример #5
0
    /// <summary>
    /// 解压缩文件(压缩文件中含有子目录)
    /// </summary>
    /// <param name="zipfilepath">待解压缩的文件路径</param>
    /// <param name="unzippath">解压缩到指定目录</param>
    /// <returns>解压后的文件列表</returns>
    public static void UnZipDir(string zipfilepath, string unzippath, ZipProgressHandler progressHandler = null, ZipCompleteHandler completeHandler = null, ZipErrorHandler errorHandler = null, bool replace = true)
    {
        try
        {
            using (FileStream filestream = File.OpenRead(zipfilepath))
            {
                string zipfilename = Path.GetFileName(zipfilepath);

                //检查输出目录是否以“\\”结尾
                if (unzippath.EndsWithNonAlloc("/") == false || unzippath.EndsWithNonAlloc(":/") == false)
                {
                    unzippath += "/";
                }
                ZipInputStream s = new ZipInputStream(filestream);

                string directoryName = Path.GetDirectoryName(unzippath);
                //生成解压目录【用户解压到硬盘根目录时,不需要创建】
                if (!string.IsNullOrEmpty(directoryName))
                {
                    Directory.CreateDirectory(directoryName);
                }


                string   filePath;
                string   fileName;
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    fileName = Path.GetFileName(theEntry.Name);
                    long read_size = 0;

                    if (!string.IsNullOrEmpty(fileName))
                    {
                        //如果文件的压缩后大小为0那么说明这个文件是空的,因此不需要进行读出写入
                        if (theEntry.CompressedSize == 0)
                        {
                            break;
                        }

                        filePath = string.Format("{0}{1}", unzippath, theEntry.Name);
                        filePath = filePath.Replace("\\", "/");

                        if (replace == false && File.Exists(filePath))
                        {
                            continue;
                        }

                        //建立下面的目录和子目录
                        Directory.CreateDirectory(Path.GetDirectoryName(filePath));

                        FileStream streamWriter = File.Create(filePath);

                        int    size = 1024;
                        byte[] data = new byte[1024];
                        while (true)
                        {
                            size = s.Read(data, 0, data.Length);
                            if (size > 0)
                            {
                                read_size += size;
                                streamWriter.Write(data, 0, size);
                                if (progressHandler != null)
                                {
                                    string message = string.Format("{0}({1})", zipfilename, Path.GetFileNameWithoutExtension(theEntry.Name));
                                    progressHandler(message, read_size, s.Length);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        streamWriter.Close();
                    }
                }
                s.Dispose();
                s.Close();
                //GC.Collect();
                if (completeHandler != null)
                {
                    completeHandler();
                }
            }
        }
        catch (Exception e)
        {
            if (errorHandler != null)
            {
                errorHandler(e.Message);
            }
            DebugLogger.Log(e);
        }
    }