C# 用GZipStream 压缩流来压缩和解压文件

最近在用c#做一些工作,其中需要把文件进行压缩和解压。
有很多种方法,其中比较成熟的就是用别人的类。
可以参考博客c#压缩文件

比较简单的方式就是用流压缩,将要写入的数据变成字节型数组,直接写入流中即可。

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 文件流
{
 public partial class Form1 : Form
 {
 public Form1()
 {
  InitializeComponent();
 }
 private void button1_Click(object sender, EventArgs e)
 {
  string s = "压缩文件实验";

  SaveFileDialog sf = new SaveFileDialog()
            {
                //设置文件保存类型
                Filter = "zif文件|*.zif|所有文件|*.*",
                //如果用户没有输入扩展名,自动追加后缀
                AddExtension = true,
                //设置标题
                Title = "存文件",
                //设置默认文件类型显示顺序 
                FilterIndex = 1,

                //保存对话框是否记忆上次打开的目录 
                RestoreDirectory = true
            };
            //如果用户点击了保存按钮
            if (sf.ShowDialog() == DialogResult.OK)
            {
                //实例化一个文件流--->与写入文件相关联
                FileStream fs = new FileStream(sf.FileName, FileMode.Create);

                //将字符串转成字节数组
                var bytes = System.Text.Encoding.Default.GetBytes(s);

                //开始写入(直接写入文件了)
                //fs.Write(bytes , 0, bytes .Length);

                using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress))   //代开压缩文件流
                {
                    zipStream.Write(bytes, 0, bytes.Length);  //写入压缩文件
                    MessageBox.Show("压缩成功!");
                }
            }
 }



//解压写的不好
 private void button2_Click(object sender, EventArgs e)
     {
      OpenFileDialog ofd = new OpenFileDialog()
            {
                Filter = "压缩 files (*.zif)|*.zif|All files (*.*)|*.*"//文件过滤选择
            };
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read))
                {
                    using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Decompress))
                    {                                  
                        int bytesRead;
                        byte[] bytes = new byte[1024*1024*4];   //超大数组,先把数据全部复制出来。
                        while ((bytesRead = zipStream.Read(bytes, 0, bytes.Length)) > 0)//bytetesRead是读出来的字节数
                        {
                            try
                            {
                                byte[] longbindata = new byte[bytesRead];
                                Array.Copy(bytes, 0, longbindata, 0, bytesRead);
                                System.Diagnostics.Trace.WriteLine(longbindata[0].ToString());
                            }
                            catch (Exception ex)
                            {
                                System.Diagnostics.Trace.WriteLine(ex.Message);
                            }               
                        }
                        MessageBox.Show("解压成功!");
                        //}

                    }
                }
            }
    }
}

上次那个解压操作需要设置一个超大数组,这简直就是不人性化呀,查询了很久,找到另外一种方法:
第一个函数,将流转成字节数组:

        public byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }

第二个函数,将流转成的字节数组传入以下函数,则可以返回解压之后的字节数组:

        public static byte[] Decompress(byte[] bytes)
        {
            using (var compressStream = new MemoryStream(bytes))
            {
                using (var zipStream = new GZipStream(compressStream, CompressionMode.Decompress))
                {
                    using (var resultStream = new MemoryStream())
                    {
                        zipStream.CopyTo(resultStream);
                        return resultStream.ToArray();
                    }
                }
            }
        }

所以解压过程就很人性化:data即是所需要的数组。

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog()
            {
                Filter = "压缩 files (*.zif)|*.zif|All files (*.*)|*.*"//文件过滤选择
            };

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                byte[] data = null;            
                using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read))
                {
                    data = StreamToBytes(fs);
                    data = Decompress(data);
                }
            }
        }

你可能感兴趣的:(Basic,C_C++_C#_Java)