C# GZipStream 压缩 解压

关于GZipStream压缩解压,网上找了很多资料,完整的不多,要么是针对字符串压缩解压缩的,要么只实现了针对单个文件的压缩解压缩,还有的不支持子文件夹的压缩,实用性都不是很大。

以下整理了压缩解压缩的代码,供以后拿出来翻阅,在项目中可以直接使用这3个类,已通过测试。

1.首先是有一个描述要压缩的文件类GZipFileInfo,包含了一些文件信息

/// <summary>
/// 要压缩的文件信息
/// </summary>
public class GZipFileInfo
{
/// <summary>
/// 文件索引
/// </summary>
public int Index = 0;
/// <summary>
/// 文件相对路径,‘/‘
/// </summary>
public string RelativePath = null;
public DateTime ModifiedDate;
/// <summary>
/// 文件内容长度
/// </summary>
public int Length = 0;
public bool AddedToTempFile = false;
public bool RestoreRequested = false;
public bool Restored = false;
/// <summary>
/// 文件绝对路径,‘\‘
/// </summary>
public string LocalPath = null;
public string Folder = null;

public bool ParseFileInfo(string fileInfo)
{
bool success = false;
try
{
if (!string.IsNullOrEmpty(fileInfo))
{
// get the file information
string[] info = fileInfo.Split(‘,‘);
if (info != null && info.Length == 4)
{
this.Index = Convert.ToInt32(info[0]);
this.RelativePath = info[1].Replace("/", "\\");
this.ModifiedDate = Convert.ToDateTime(info[2]);
this.Length = Convert.ToInt32(info[3]);
success = true;
}
}
}
catch
{
success = false;
}
return success;
}
}

2.压缩后生成的压缩包信息GZipResult,描述了压缩包的一些属性,包括大小,文件数,以及其中的每一个文件

/// <summary>
/// 文件压缩后的压缩包类
/// </summary>
public class GZipResult
{
/// <summary>
/// 压缩包中包含的所有文件,包括子目录下的文件
/// </summary>
public GZipFileInfo[] Files = null;
/// <summary>
/// 要压缩的文件数
/// </summary>
public int FileCount = 0;
public long TempFileSize = 0;
public long ZipFileSize = 0;
/// <summary>
/// 压缩百分比
/// </summary>
public int CompressionPercent = 0;
/// <summary>
/// 临时文件
/// </summary>
public string TempFile = null;
/// <summary>
/// 压缩文件
/// </summary>
public string ZipFile = null;
/// <summary>
/// 是否删除临时文件
/// </summary>
public bool TempFileDeleted = false;
public bool Errors = false;
}

3.压缩操作类GZip,包括压缩解压等操作

?

/// <summary>

/// 压缩文件类

/// </summary>

public class GZip

{

    /// <summary>

    /// Compress

    /// </summary>

    /// <param name="lpSourceFolder">The location of the files to include in the zip file, all files including files in subfolders will be included.</param>

    /// <param name="lpDestFolder">Folder to write the zip file into</param>

    /// <param name="zipFileName">Name of the zip file to write</param>

    public static GZipResult Compress(string lpSourceFolder, string lpDestFolder, string zipFileName)

    {

        return Compress(lpSourceFolder, "*.*", SearchOption.AllDirectories, lpDestFolder, zipFileName, true);

    }

    /// <summary>

    /// Compress

    /// </summary>

    /// <param name="lpSourceFolder">The location of the files to include in the zip file</param>

    /// <param name="searchPattern">Search pattern (ie "*.*" or "*.txt" or "*.gif") to idendify what files in lpSourceFolder to include in the zip file</param>

    /// <param name="searchOption">Only files in lpSourceFolder or include files in subfolders also</param>

    /// <param name="lpDestFolder">Folder to write the zip file into</param>

    /// <param name="zipFileName">Name of the zip file to write</param>

    /// <param name="deleteTempFile">Boolean, true deleted the intermediate temp file, false leaves the temp file in lpDestFolder (for debugging)</param>

    public static GZipResult Compress(string lpSourceFolder, string searchPattern, SearchOption searchOption, string lpDestFolder, string zipFileName, bool deleteTempFile)

    {

        DirectoryInfo di = new DirectoryInfo(lpSourceFolder);

        FileInfo[] files = di.GetFiles("*.*", searchOption);

        return Compress(files, lpSourceFolder, lpDestFolder, zipFileName, deleteTempFile);

    }

    /// <summary>

    /// Compress

    /// </summary>

    /// <param name="files">Array of FileInfo objects to be included in the zip file</param>

    /// <param name="lpBaseFolder">Base folder to use when creating relative paths for the files

    /// stored in the zip file. For example, if lpBaseFolder is ‘C:\zipTest\Files\‘, and there is a file

    /// ‘C:\zipTest\Files\folder1\sample.txt‘ in the ‘files‘ array, the relative path for sample.txt

    /// will be ‘folder1/sample.txt‘</param>

    /// <param name="lpDestFolder">Folder to write the zip file into</param>

    /// <param name="zipFileName">Name of the zip file to write</param>

    public static GZipResult Compress(FileInfo[] files, string lpBaseFolder, string lpDestFolder, string zipFileName)

    {

        return Compress(files, lpBaseFolder, lpDestFolder, zipFileName, true);

    }

    /// <summary>

    /// Compress

    /// </summary>

    /// <param name="files">Array of FileInfo objects to be included in the zip file</param>

    /// <param name="lpBaseFolder">Base folder to use when creating relative paths for the files

    /// stored in the zip file. For example, if lpBaseFolder is ‘C:\zipTest\Files\‘, and there is a file

    /// ‘C:\zipTest\Files\folder1\sample.txt‘ in the ‘files‘ array, the relative path for sample.txt

    /// will be ‘folder1/sample.txt‘</param>

    /// <param name="lpDestFolder">Folder to write the zip file into</param>

    /// <param name="zipFileName">Name of the zip file to write</param>

    /// <param name="deleteTempFile">Boolean, true deleted the intermediate temp file, false leaves the temp file in lpDestFolder (for debugging)</param>

    public static GZipResult Compress(FileInfo[] files, string lpBaseFolder, string lpDestFolder, string zipFileName, bool deleteTempFile)

    {

        GZipResult result = new GZipResult();

        try

        {

            if (!lpDestFolder.EndsWith("\\"))

            {

                lpDestFolder += "\\";

            }

            string lpTempFile = lpDestFolder + zipFileName + ".tmp";

            string lpZipFile = lpDestFolder + zipFileName;

            result.TempFile = lpTempFile;

            result.ZipFile = lpZipFile;

            if (files != null && files.Length > 0)

            {

                CreateTempFile(files, lpBaseFolder, lpTempFile, result);

                if (result.FileCount > 0)

                {

                    CreateZipFile(lpTempFile, lpZipFile, result);

                }

                // delete the temp file

                if (deleteTempFile)

                {

                    File.Delete(lpTempFile);

                    result.TempFileDeleted = true;

                }

            }

        }

        catch //(Exception ex4)

        {

            result.Errors = true;

        }

        return result;

    }

    private static void CreateZipFile(string lpSourceFile, string lpZipFile, GZipResult result)

    {

        byte[] buffer;

        int count = 0;

        FileStream fsOut = null;

        FileStream fsIn = null;

        GZipStream gzip = null;

        // compress the file into the zip file

        try

        {

            fsOut = new FileStream(lpZipFile, FileMode.Create, FileAccess.Write, FileShare.None);

            gzip = new GZipStream(fsOut, CompressionMode.Compress, true);

            fsIn = new FileStream(lpSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);

            buffer = new byte[fsIn.Length];

            count = fsIn.Read(buffer, 0, buffer.Length);

            fsIn.Close();

            fsIn = null;

            // compress to the zip file

            gzip.Write(buffer, 0, buffer.Length);

            result.ZipFileSize = fsOut.Length;

            result.CompressionPercent = GetCompressionPercent(result.TempFileSize, result.ZipFileSize);

        }

        catch //(Exception ex1)

        {

            result.Errors = true;

        }

        finally

        {

            if (gzip != null)

            {

                gzip.Close();

                gzip = null;

            }

            if (fsOut != null)

            {

                fsOut.Close();

                fsOut = null;

            }

            if (fsIn != null)

            {

                fsIn.Close();

                fsIn = null;

            }

        }

    }

    private static void CreateTempFile(FileInfo[] files, string lpBaseFolder, string lpTempFile, GZipResult result)

    {

        byte[] buffer;

        int count = 0;

        byte[] header;

        string fileHeader = null;

        string fileModDate = null;

        string lpFolder = null;

        int fileIndex = 0;

        string lpSourceFile = null;

        string vpSourceFile = null;

        GZipFileInfo gzf = null;

        FileStream fsOut = null;

        FileStream fsIn = null;

        if (files != null && files.Length > 0)

        {

            try

            {

                result.Files = new GZipFileInfo[files.Length];

                // open the temp file for writing

                fsOut = new FileStream(lpTempFile, FileMode.Create, FileAccess.Write, FileShare.None);

                foreach (FileInfo fi in files)

                {

                    lpFolder = fi.DirectoryName + "\\";

                    try

                    {

                        gzf = new GZipFileInfo();

                        gzf.Index = fileIndex;

                        // read the source file, get its virtual path within the source folder

                        lpSourceFile = fi.FullName;

                        gzf.LocalPath = lpSourceFile;

                        vpSourceFile = lpSourceFile.Replace(lpBaseFolder, string.Empty);

                        vpSourceFile = vpSourceFile.Replace("\\", "/");

                        gzf.RelativePath = vpSourceFile;

                        fsIn = new FileStream(lpSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);

                        buffer = new byte[fsIn.Length];

                        count = fsIn.Read(buffer, 0, buffer.Length);

                        fsIn.Close();

                        fsIn = null;

                        fileModDate = fi.LastWriteTimeUtc.ToString();

                        gzf.ModifiedDate = fi.LastWriteTimeUtc;

                        gzf.Length = buffer.Length;

                        fileHeader = fileIndex.ToString() + "," + vpSourceFile + "," + fileModDate + "," + buffer.Length.ToString() + "\n";

                        header = Encoding.Default.GetBytes(fileHeader);

                        fsOut.Write(header, 0, header.Length);

                        fsOut.Write(buffer, 0, buffer.Length);

                        fsOut.WriteByte(10); // linefeed

                        gzf.AddedToTempFile = true;

                        // update the result object

                        result.Files[fileIndex] = gzf;

                        // increment the fileIndex

                        fileIndex++;

                    }

                    catch //(Exception ex1)

                    {

                        result.Errors = true;

                    }

                    finally

                    {

                        if (fsIn != null)

                        {

                            fsIn.Close();

                            fsIn = null;

                        }

                    }

                    if (fsOut != null)

                    {

                        result.TempFileSize = fsOut.Length;

                    }

                }

            }

            catch //(Exception ex2)

            {

                result.Errors = true;

            }

            finally

            {

                if (fsOut != null)

                {

                    fsOut.Close();

                    fsOut = null;

                }

            }

        }

        result.FileCount = fileIndex;

    }

    public static GZipResult Decompress(string lpSourceFolder, string lpDestFolder, string zipFileName)

    {

        return Decompress(lpSourceFolder, lpDestFolder, zipFileName, true, true, null, null, 4096);

    }

    public static GZipResult Decompress(string lpSourceFolder, string lpDestFolder, string zipFileName, bool writeFiles, string addExtension)

    {

        return Decompress(lpSourceFolder, lpDestFolder, zipFileName, true, writeFiles, addExtension, null, 4096);

    }

    public static GZipResult Decompress(string lpSrcFolder, string lpDestFolder, string zipFileName,

        bool deleteTempFile, bool writeFiles, string addExtension, Hashtable htFiles, int bufferSize)

    {

        GZipResult result = new GZipResult();

        if (!lpDestFolder.EndsWith("\\"))

        {

            lpDestFolder += "\\";

        }

        string lpTempFile = lpSrcFolder + zipFileName + ".tmp";

        string lpZipFile = lpSrcFolder + zipFileName;

        result.TempFile = lpTempFile;

        result.ZipFile = lpZipFile;

        string line = null;

        string lpFilePath = null;

        string lpFolder = null;

        GZipFileInfo gzf = null;

        FileStream fsTemp = null;

        ArrayList gzfs = new ArrayList();

        bool write = false;

        if (string.IsNullOrEmpty(addExtension))

        {

            addExtension = string.Empty;

        }

        else if (!addExtension.StartsWith("."))

        {

            addExtension = "." + addExtension;

        }

        // extract the files from the temp file

        try

        {

            fsTemp = UnzipToTempFile(lpZipFile, lpTempFile, result);

            if (fsTemp != null)

            {

                while (fsTemp.Position != fsTemp.Length)

                {

                    line = null;

                    while (string.IsNullOrEmpty(line) && fsTemp.Position != fsTemp.Length)

                    {

                        line = ReadLine(fsTemp);

                    }

                    if (!string.IsNullOrEmpty(line))

                    {

                        gzf = new GZipFileInfo();

                        if (gzf.ParseFileInfo(line) && gzf.Length > 0)

                        {

                            gzfs.Add(gzf);

                            lpFilePath = lpDestFolder + gzf.RelativePath;

                            lpFolder = GetFolder(lpFilePath);

                            gzf.LocalPath = lpFilePath;

                            write = false;

                            if (htFiles == null || htFiles.ContainsKey(gzf.RelativePath))

                            {

                                gzf.RestoreRequested = true;

                                write = writeFiles;

                            }

                            if (write)

                            {

                                // make sure the folder exists

                                if (!Directory.Exists(lpFolder))

                                {

                                    Directory.CreateDirectory(lpFolder);

                                }

                                // read from fsTemp and write out the file

                                gzf.Restored = WriteFile(fsTemp, gzf.Length, lpFilePath + addExtension, bufferSize);

                            }

                            else

                            {

                                // need to advance fsTemp

                                fsTemp.Position += gzf.Length;

                            }

                        }

                    }

                }

            }

        }

        catch //(Exception ex3)

        {

            result.Errors = true;

        }

        finally

        {

            if (fsTemp != null)

            {

                fsTemp.Close();

                fsTemp = null;

            }

        }

        // delete the temp file

        try

        {

            if (deleteTempFile)

            {

                File.Delete(lpTempFile);

                result.TempFileDeleted = true;

            }

        }

        catch //(Exception ex4)

        {

            result.Errors = true;

        }

        result.FileCount = gzfs.Count;

        result.Files = new GZipFileInfo[gzfs.Count];

        gzfs.CopyTo(result.Files);

        return result;

    }

    private static string ReadLine(FileStream fs)

    {

        string line = string.Empty;

        const int bufferSize = 4096;

        byte[] buffer = new byte[bufferSize];

        byte b = 0;

        byte lf = 10;

        int i = 0;

        while (b != lf)

        {

            b = (byte)fs.ReadByte();

            buffer[i] = b;

            i++;

        }

        line = System.Text.Encoding.Default.GetString(buffer, 0, i - 1);

        return line;

    }

    private static bool WriteFile(FileStream fs, int fileLength, string lpFile, int bufferSize)

    {

        bool success = false;

        FileStream fsFile = null;

        if (bufferSize == 0 || fileLength < bufferSize)

        {

            bufferSize = fileLength;

        }

        int count = 0;

        int remaining = fileLength;

        int readSize = 0;

        try

        {

            byte[] buffer = new byte[bufferSize];

            fsFile = new FileStream(lpFile, FileMode.Create, FileAccess.Write, FileShare.None);

            while (remaining > 0)

            {

                if (remaining > bufferSize)

                {

                    readSize = bufferSize;

                }

                else

                {

                    readSize = remaining;

                }

                count = fs.Read(buffer, 0, readSize);

                remaining -= count;

                if (count == 0)

                {

                    break;

                }

                fsFile.Write(buffer, 0, count);

                fsFile.Flush();

            }

            fsFile.Flush();

            fsFile.Close();

            fsFile = null;

            success = true;

        }

        catch //(Exception ex2)

        {

            success = false;

        }

        finally

        {

            if (fsFile != null)

            {

                fsFile.Flush();

                fsFile.Close();

                fsFile = null;

            }

        }

        return success;

    }

    private static string GetFolder(string lpFilePath)

    {

        string lpFolder = lpFilePath;

        int index = lpFolder.LastIndexOf("\\");

        if (index != -1)

        {

            lpFolder = lpFolder.Substring(0, index + 1);

        }

        return lpFolder;

    }

    private static FileStream UnzipToTempFile(string lpZipFile, string lpTempFile, GZipResult result)

    {

        FileStream fsIn = null;

        GZipStream gzip = null;

        FileStream fsOut = null;

        FileStream fsTemp = null;

        const int bufferSize = 4096;

        byte[] buffer = new byte[bufferSize];

        int count = 0;

        try

        {

            fsIn = new FileStream(lpZipFile, FileMode.Open, FileAccess.Read, FileShare.Read);

            result.ZipFileSize = fsIn.Length;

            fsOut = new FileStream(lpTempFile, FileMode.Create, FileAccess.Write, FileShare.None);

            gzip = new GZipStream(fsIn, CompressionMode.Decompress, true);

            while (true)

            {

                count = gzip.Read(buffer, 0, bufferSize);

                if (count != 0)

                {

                    fsOut.Write(buffer, 0, count);

                }

                if (count != bufferSize)

                {

                    break;

                }

            }

        }

        catch //(Exception ex1)

        {

            result.Errors = true;

        }

        finally

        {

            if (gzip != null)

            {

                gzip.Close();

                gzip = null;

            }

            if (fsOut != null)

            {

                fsOut.Close();

                fsOut = null;

            }

            if (fsIn != null)

            {

                fsIn.Close();

                fsIn = null;

            }

        }

        fsTemp = new FileStream(lpTempFile, FileMode.Open, FileAccess.Read, FileShare.None);

        if (fsTemp != null)

        {

            result.TempFileSize = fsTemp.Length;

        }

        return fsTemp;

    }

    private static int GetCompressionPercent(long tempLen, long zipLen)

    {

        double tmp = (double)tempLen;

        double zip = (double)zipLen;

        double hundred = 100;

        double ratio = (tmp - zip) / tmp;

        double pcnt = ratio * hundred;

        return (int)pcnt;

    }

}

压缩解压缩的操作如下:

//Compress三个参数分别是“要压缩的目标目录”,“保存压缩文件的目录”,压缩文件名
GZip.Compress(@"E:\much\", @"E:\much\", "ziptest");

//Decompress三个参数分别是"压缩包所在目录","要解压到的目录",“压缩包名”
//如果压缩包所在目录不存在则解压不会成功
GZip.Decompress(@"E:\much\zip\", @"E:\much\zip\", "ziptest");

时间: 2024-10-10 16:53:37

C# GZipStream 压缩 解压的相关文章

WebAPI性能优化之压缩解压

有时候为了提升WebAPI的性能,减少响应时间,我们会使用压缩和解压,而现在大多数客户端浏览器都提供了内置的解压支持.在WebAPI请求的资源越大时,使用压缩对性能提升的效果越明显,而当请求的资源很小时则不需要使用压缩和解压,因为压缩和解压同样也是需要耗费一定的时间的. 看见老外写了一篇ASP.NET Web API GZip compression ActionFilter with 8 lines of code 说实话被这标题吸引了,8行代码实现GZip压缩过滤器,我就照着他的去实践了一番

Lniux常见的压缩/解压命令小结

转载请注明: 导航制导与控制实验室 2014年12月16日 在linux开发过程中,经常会遇资料的打包/解包.压缩/解压:本文我将在linux系统中常用的命令进行了整理和分类,内容如下: 1.tar 命令,主要是对Dir先归档,在借助其他命令处理归档文件: 2.单个文件的压缩命令,对单个文件进行处理的命令,有时也可以借助tar命令对目录先打包,再进行压缩: 3.zip.rar压缩命令,即可对单个文件也可对目录进行压缩处理,该方法利于不同操作系统的处理: 该文章只是作者本人的理解,有些命令还会验证

压缩&amp;&amp;解压命令汇总

以下是搜集的Linux系统下,压缩&&解压命令,以备参考使用. .tar 解包: tar xvf FileName.tar 打包:tar cvf FileName.tar DirName    tar cvf a.tar a.txt b.txt c.txt (注:tar是打包,不是压缩!) --------------------------------------------- .gz 解压1:gunzip FileName.gz 解压2:gzip -d FileName.gz 压缩:g

支持文件的流式压缩/解压IP*Works! Zip

IP*Works! Zip是为应用程序添加压缩功能的完全可控件组件包.使用简单.速度快并且效率很高,是一个为桌面和网上应用程序添加压缩和解压缩功能的组件套包./n software IP*Works! Zip支持Zip.Tar.Gzip 和 Jar压缩标准,特别的,它支持流式压缩.加密压缩,在压缩包里就可以直接删除文件.我们目前提供完全可控的纯C# .NET组件.纯Java Beans. 产品特征: IP*Works! Zip基于纯C#代码,是完全可控的.NET组件,不依赖于任何外部代码.是完全

Lucene4.2源码解析之fdt和fdx文件的读写——fdx文件存储一个个的Block,每个Block管理着一批Chunk,通过docID读取到document需要完成Segment、Block、Chunk、document四级查询,引入了LZ4算法对fdt的chunk docs进行了实时压缩/解压

前言 通常在搜索打分完毕后,IndexSearcher会返回一个docID序列,但是仅仅有docID我们是无法看到存储在索引中的document,这时候就需要通过docID来得到完整Document信息,这个过程就需要对fdx/fdt文件进行读操作.为了更清楚地了解fdx/fdt文件的作用,本文把fdx/fdt文件的读和写整合到了一起,尽管这在Lucene中是两个分开的过程. 1. 索引生成阶段 索引生成阶段包含着一个复杂的过程,所以了解本文前最好对Lucene的索引架构有一定的了解,可以参考博

linux下各种文件压缩解压(转载)

Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进 行压缩了,所以首先就来讲讲tar命令的基本用法:  tar命令的选项有很多(用man tar可以查看到),但常用的就那么几个选项,下面 来举例说明一下:  # tar -cf all.tar *.jpg  这条命令是将所有.jpg的文件打成一个名为all.tar的包.-c是表示产生新的包 ,-f指定包的文件名.  # tar -

Centos压缩&解压

centos中的文件压缩与解压用得频率还是较大的,许多的压缩软件都是下载到linux系统上,然后解压安装,使用的是 tar 命令,这个命令又有主选项和辅助选项,这里就来总结一下吧,以方便自己的使用. Tar 语法:tar [主选项+辅选项] 文件或者目录 主选项: c 创建新的档案文件.如果用户想备份一个目录或是一些文件,就要选择这个选项.相当于打包. x 从档案文件中释放文件.相当于拆包. t 列出档案文件的内容,查看已经备份了哪些文件. 特别注意,在参数的下达中, c/x/t 仅能存在一个!

SAPCAR 压缩解压软件的使用方法

SAPCAR 是 SAP 公司使用的压缩解压软件,从 SAP 网站下载的补丁包和小型软件基本都是扩展名为 car 或 sar 的,它们都可以用 SAPCAR 来解压.下面是它的使用说明: 用法: 创建新档案:SAPCAR -c[vir][f archive] [-P] [-C directory]   [-A filename] [-T filename] [-X filename]   [-p value] [-V] file1 file2 ... 列出一个档案的内容:SAPCAR -t[vs

Linux压缩解压工具--日常学习

Date:2017-04-08 命令(对应格式):gzip(.gz)  bzip2(.bz2)  xz(.xz)  compress(.z)   tar(.tar) 1.gzip 语法:gzip  选项  FILE 常用选项:-d   -#    -c (1)-d(decompressiom):解压 解压的方式有两种:"gizp  -d   FILE" 和"gunzip  FIEL" eg: tmp]# ls -lh messages(-h:human-readdb