网络通信 数据压缩后发送

基础知识介绍 目的:
数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据压缩,两者本质上没啥区别,在数学家看来,都是映射。一方面在进行通信的时候,有必要将待传输的数据进行压缩,以减少带宽需求;另一方面,计算机存储数据的时候,为了减少磁盘容量需求,也会将文件进行压缩,尽管现在的网络带宽越来越高,压缩已经不像90年代初那个时候那么迫切,但在很多场合下仍然需要,其中一个原因是压缩后的数据容量减小后,磁盘访问IO的时间也缩短,尽管压缩和解压缩过程会消耗CPU资源,但是CPU计算资源增长得很快,但是磁盘IO资源却变化得很慢,比如目前主流的SATA硬盘仍然是7200转,如果把磁盘的IO压力转化到CPU上,总体上能够提升系统运行速度。压缩作为一种非常典型的技术,会应用到很多很多场合下,比如文件系统、数据库、消息传输、网页传输等等各类场合。尽管压缩里面会涉及到很多术语和技术,但无需担心,博主尽量将其描述得通俗易懂。另外,本文涉及的压缩算法非常主流并且十分精巧,理解了ZIP的压缩过程,对理解其它相关的压缩算法应该就比较容易了

 

步骤:

文件目录:D:\\temp\\Recovered\\  

a.对目前数据中的Data部分转换成字符串后,存入一个NewGuid().txt文本中,然后对这个文本进行压缩

b.把压缩文件的文件流存在一个字典缓存中
key:终端号  value:压缩后文件(NewGuid().tar)的byte[]

c.从字典中取出文件,每次读取180个字节,替换原来的Data部分,其余不变

d.当  if (rd.NO == rd.TotalNum) 标志最后一包数据
这个时候把刚刚生成的txt文件和tar文件删除掉

 

2.文件压缩方法

public class ArgHelper
    {
        public static string FindArg(string[] args, string name)
        {
            foreach (string s in args)
            {
                if (s.StartsWith(name + "=", StringComparison.OrdinalIgnoreCase))
                    return s.Substring(name.Length + 1);
            }
            return "";
        }
    }

    public class FileZipHelper
    {

  /// <summary>
        /// 压缩单个文件
        /// </summary>
        /// <param name="singlefile">压缩对象名称 比如D:\1.txt</param>
        /// <param name="targetentryfilename">压缩后的对象名称 比如D:\1.tar</param>
        /// <returns></returns>
        public static int ZipSinglefile(string singlefile, string targetentryfilename = "")
        {
            if (!System.IO.File.Exists(singlefile))
                throw new System.IO.FileNotFoundException(singlefile);

            if (targetentryfilename == "")
                targetentryfilename = singlefile;

            // using (FileStream fs = new FileStream(singlefile + ".tgz", FileMode.Create, FileAccess.Write, FileShare.None))
            //对其进行修改 后缀名为 Tar
            using (FileStream fs = new FileStream(targetentryfilename, FileMode.Create, FileAccess.Write, FileShare.None))
            using (Stream gzipStream = new GZipOutputStream(fs))
            using (TarArchive tarArchive = TarArchive.CreateOutputTarArchive(gzipStream))
            {
                tarArchive.RootPath = System.IO.Path.GetDirectoryName(targetentryfilename).Replace(Path.DirectorySeparatorChar, '/');
                TarEntry tarEntry = TarEntry.CreateEntryFromFile(singlefile);
                tarEntry.Name = targetentryfilename.Replace(Path.DirectorySeparatorChar, '/');
                tarArchive.WriteEntry(tarEntry, true);
                tarArchive.Close();
            }
            return 0;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args">
        /// <example>
        /// <code>
        ///  args = new string[] { 
        ///     "ZipFile", 
        ///     @"Path=D:\kljob\CardLan\CardLan.Web.OneCard", 
        ///     "Filter=*.cshtml;*.js", 
        ///     "TargetFile=d:\\temp\\zip.zip" ,
        ///     "ZipType=DotNet",
        ///     "SkipPath=DebugJS;bin" 
        ///  };
        /// 
        /// </code>
        /// </example>
        /// </param>
        /// <returns></returns>
        public static int Zip(string[] args)
        {
            string path = Helper.ArgHelper.FindArg(args, "Path"); //文件目录
            string targetFile = Helper.ArgHelper.FindArg(args, "TargetFile"); //目标文件
            string zipType = Helper.ArgHelper.FindArg(args, "ZipType");//压缩类型
            string filter = Helper.ArgHelper.FindArg(args, "Filter");//过滤选项
            string skipPath = Helper.ArgHelper.FindArg(args, "SkipPath");//忽略目录

            //System.Windows.Forms.MessageBox.Show(string.Join(",",args));
            if (!System.IO.Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            switch (zipType)
            {
                case "DotNet":
                default:
                    using (ZipFile zip = new ZipFile(System.Text.Encoding.UTF8))//设置编码,解决压缩文件时中文乱码
                    {
                        StringBuilder sb = new StringBuilder("");
                        foreach (var item in skipPath.Split(';'))
                        {
                            if (!string.IsNullOrEmpty(item))
                                sb.AppendFormat("name!={1}\\{0}\\* and ", item, path);
                        }
                        zip.AddSelectedFiles(sb.ToString() + "  (name=" + string.Join(" or name=", filter.Split(';')) + ")", path, "", true);
                        zip.Save(targetFile);
                    }
                    return 0;
                case "TGZ":
                    using (FileStream fs = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None))
                    using (Stream gzipStream = new GZipOutputStream(fs))
                    using (TarArchive tarArchive = TarArchive.CreateOutputTarArchive(gzipStream))
                    {
                        tarArchive.RootPath = path.TrimEnd('\\').Replace(Path.DirectorySeparatorChar, '/'); ;
                        AddDirectoryFilesToTar(tarArchive, path, skipPath, filter, true);
                    }
                    return 0;
            }
        }

        /// <summary>
        /// 解压文件
        /// </summary>
        /// <param name="args">
        /// <example>
        /// <code>
        /// args = new string[] {
        ///           "UnZipFile", 
        ///           @"TargetPath=D:\temp\testzip", 
        ///           "File=d:\\temp\\zip.zip" ,
        ///           "ZipType=DotNet"  
        ///   };
        /// 
        /// </code>
        /// </example>
        /// </param>
        /// <returns></returns>
        public static int UnZip(string[] args)
        {
            string file = Helper.ArgHelper.FindArg(args, "File");
            string targetPath = Helper.ArgHelper.FindArg(args, "TargetPath");
            string zipType = Helper.ArgHelper.FindArg(args, "ZipType");
            if (!System.IO.Directory.Exists(targetPath))
                System.IO.Directory.CreateDirectory(targetPath);

            switch (zipType)
            {
                case "DotNet":
                default:
                    using (ZipFile zip = ZipFile.Read(file))
                    {
                        zip.ExtractAll(targetPath, ExtractExistingFileAction.OverwriteSilently);
                    }
                    return 0;
                case "TGZ":
                    Stream inStream = File.OpenRead(file);
                    Stream gzipStream = new GZipInputStream(inStream);

                    TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
                    tarArchive.ExtractContents(targetPath);
                    tarArchive.Close();

                    gzipStream.Close();
                    inStream.Close();
                    return 0;
            }
        }

        private static void AddDirectoryFilesToTar(TarArchive tarArchive, string sourceDirectory, string SkipPath, string Filter, bool recurse)
        {
            // Recursively add sub-folders
            if (recurse)
            {
                string[] directories = Directory.GetDirectories(sourceDirectory);
                foreach (string directory in directories)
                {
                    bool flag = false;
                    foreach (var r in SkipPath.Split(';'))
                    {
                        if (directory.EndsWith("\\" + r, StringComparison.OrdinalIgnoreCase))
                        {
                            flag = true;
                            break;
                        }
                    }
                    if (!flag)
                        AddDirectoryFilesToTar(tarArchive, directory, SkipPath, Filter, recurse);

                }
            }

            // Add files
            List<string> fileNames = new List<string>();
            Filter.Split(';').ToList().ForEach(r =>
                fileNames.AddRange(Directory.GetFiles(sourceDirectory, r)));
            foreach (string filename in fileNames)
            {

                TarEntry tarEntry = TarEntry.CreateEntryFromFile(filename);

                tarArchive.WriteEntry(tarEntry, true);
            }
        }

       

    }

 

3.调用方法  如果Filter 为*.txt 会把目录 m_strPathRecovered 下面的所有的txt都进行压缩

                string l_strFileName = System.Guid.NewGuid().ToString();
                string l_strFileFullNameTxt = Path.Combine(m_strPathRecovered, l_strFileName + ".txt");
                string l_strFileFullNameTar = Path.Combine(m_strPathRecovered, l_strFileName + ".tar.gz");

                if (!Directory.Exists(m_strPathRecovered))
                {
                    Directory.CreateDirectory(m_strPathRecovered);
                }

                File.AppendAllText(l_strFileFullNameTxt, l_strData.ToString(), Encoding.GetEncoding("GBK"));

                CardLan.Tool.Helper.FileZipHelper.Zip(new string[]
                {
                    "ZipFile", "Path="+m_strPathRecovered,
                    "Filter=" + l_strFileName + ".txt",
                    "TargetFile="+l_strFileFullNameTar,
                    "ZipType=TGZ",
                    "SkipPath="
                });
//读取压缩包内容
File.ReadAllBytes(l_strFileFullNameTar);

 

 4.下面这个调用方法是针对于压缩单个文件的

                string l_strFileName = System.Guid.NewGuid().ToString();
                string l_strFileFullNameTxt = Path.Combine(m_strPathRecovered, l_strFileName + ".txt");
                string l_strFileFullNameTar = Path.Combine(m_strPathRecovered, l_strFileName + ".tar.gz");

                if (!Directory.Exists(m_strPathRecovered))
                {
                    Directory.CreateDirectory(m_strPathRecovered);
                }

                File.AppendAllText(l_strFileFullNameTxt, l_strData.ToString(), Encoding.GetEncoding("GBK"));

              Tool.Helper.FileZipHelper.ZipSinglefile(
                    l_strFileFullNameTxt,
                    l_strFileFullNameTar);

 

posted @ 2015-07-10 09:12  maanshancss  阅读(1627)  评论(0编辑  收藏  举报