.NET BS端和CS端相互压缩发送接收byte对象数据方法

本文是总结实际项目经验,代码不少是学习别人整合的,效果稳定可靠,有很大参考价值;但是也有不全面的地方,朋友们拿到可以按照自己需要修改。

场景是项目需要在客户端控制台软件和.NET MVC站点间互相传递数据,数据的量比较大,需要对数据进行转化为byte数据,再压缩后发送,接收方需要接收byte数据,再解压缩,还原成数据。

本文既有Web端发送接收数据,也有CS端发送接收数据,内容比较全面。


一、object和byte互转

object和byte互转是基础步骤,实现过程是很简单的,需要用到MemoryStream 、IFormatter 等类。


1、导入命名空间

using System.Collections.Generic;using System.IO;using System.Runtime.Serialization;usingSystem.Runtime.Serialization.Formatters.Binary;


2、object转byte方法

publicstaticbyte[] ToBytes(object obj)

        {

            if(obj ==null)returnnull;

            byte[] buff;

            using(MemoryStream ms =new MemoryStream())

            {

                IFormatter iFormatter =new BinaryFormatter();

                iFormatter.Serialize(ms, obj);

                buff = ms.GetBuffer();

            }

            return buff;

        }



3. byte转object

publicstaticobjectToObject(byte[] bytes)

        {

            if(bytes ==null)returnnull;

            object obj;

            using(MemoryStream ms =new MemoryStream(bytes))

            {

                IFormatter iFormatter =new BinaryFormatter();

                obj = iFormatter.Deserialize(ms);

            }

            return obj;

        }


二、使用SharpZipLib进行GZip压缩和解压

经过反复实现修改,我感觉用开源类库ICSharpCode.SharpZipLib进行GZip压缩解压比.NET自带的System.IO.Compression.GZipStream效果更好。自己感觉,数据读取成DataTable压缩,不如把DataTable转化为实体类列表进行压缩效果好。

ICSharpCode.SharpZipLib你可以很容易从网络上获取到。

如果发送方对数据进行GZip压缩,接收方必须要对数据进行GZip解压。


1、导入命名空间

using ICSharpCode.SharpZipLib.GZip;usingSystem.IO;


2.GZip压缩

publicstaticbyte[] GZipCompress(byte[] data)

        {

            byte[] bytes =null;

            using(MemoryStream o =new MemoryStream())

            {

                using(Stream s =new GZipOutputStream(o))

                {

                    s.Write(data, 0, data.Length);

                    s.Flush();

                }

                bytes = o.ToArray();

            }

            return bytes;

        }


3.GZip解压

privateconstintBUFFER_LENGTH =2048;

        publicstaticbyte[] GZipDecompress(byte[] data)

        {

            byte[] bytes =null;

            using(MemoryStream o =new MemoryStream())

            {

                using(MemoryStream ms =new MemoryStream(data))

                {

                    using(Stream s =new GZipInputStream(ms))

                    {

                        s.Flush();

                        intsize =0;

                        byte[] buffer =newbyte[BUFFER_LENGTH];

                        while((size = s.Read(buffer,0, buffer.Length)) >0)

                        {

                            o.Write(buffer, 0, size);

                        }

                    }

                }

                bytes = o.ToArray();

            }

            return bytes;

        }


三、Controller发送byte和控制台程序接收byte


1.Controller发送byte

在.NET MVC的Controller类中发送数据很简单,用Response进行如下发送就可以了,当然事先要把数据转化成byte,可以压缩也可以不压缩;但是这里的ContentType 内容表明这个数据是经过GZip压缩的。

privatevoidSendBytes(byte[] bytes)

        {

            Response.ClearContent();

            Response.ContentType ="application/x-zip-compressed";//发送的是gzip格式            Response.BinaryWrite(bytes);

            Response.End();

        }

2.控制台程序接收byte

虽然说是Controller发送byte,其实是控制台程序访问了某个url后Controller才发送数据,因此这里用PostBinary首先进行访问。

publicstaticbyte[] PostBinary(stringurl,string body, CookieContainer cookie)

        {

            HttpWebRequest request = CreateRequest(url, body, cookie);

            HttpWebResponse response = GetResponse(request);

            byte[] bytes = ReadAllBytes(response);

            return bytes;

        }


privatestaticHttpWebRequest CreateRequest(stringurl,string body, CookieContainer cookie)

        {

            Encoding encoding = Encoding.UTF8;

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            request.Method ="POST";

            request.Accept ="text/html, application/xhtml+xml, */*";

            request.ContentType ="application/x-www-form-urlencoded";

            request.CookieContainer = cookie;

            byte[] buffer = encoding.GetBytes(body);

            request.ContentLength = buffer.Length;

            request.GetRequestStream().Write(buffer, 0, buffer.Length);

            return request;

        }


privatestatic HttpWebResponse GetResponse(HttpWebRequest request)

        {

            HttpWebResponse response =null;

            try            {

                response = (HttpWebResponse)request.GetResponse();

            }

            catch (WebException ex)

            {

                response = (HttpWebResponse)ex.Response;

            }

            return response;

        }



ReadAllBytes方法要用到MemoryStream 类。

publicstaticbyte[] ReadAllBytes(HttpWebResponse response)

        {

            Stream responseStream = response.GetResponseStream();

            intbufferSize =2048;

            MemoryStream ms =new MemoryStream();

            byte[] buffer =newbyte[bufferSize];

            while(true)

            {

                intsize = responseStream.Read(buffer,0, bufferSize);

                if(size ==0)break;

                ms.Write(buffer, 0, size);

            }

            byte[] responseBytes = ms.ToArray();

            return responseBytes;

        }



四、控制台程序发送byte和Controller接收byte

这一部分和上一部分相反。控制台程序发送byte其实和向网站上传文件一样,Controller接收byte其实也和接收上传的文件一样。


1.控制台程序发送byte

这是是用HttpWebRequest给指定url上传文件,文件当然是按byte格式上传的。

publicstaticHttpWebResponse UploadBinary(stringurl,stringdataName,object obj)

        {

            byte[] dataBytes = ObjectBinaryHelper.Compress(obj);

            if(dataBytes ==null) dataBytes =newbyte[] { };

            stringboundary = DateTime.Now.Ticks.ToString("x");

            HttpWebRequest uploadRequest = (HttpWebRequest)WebRequest.Create(url);//url为上传的地址uploadRequest.ContentType ="multipart/form-data; boundary="+ boundary;

            uploadRequest.Method ="POST";

            uploadRequest.Accept ="*/*";

            uploadRequest.KeepAlive =true;

            uploadRequest.Headers.Add("Accept-Language","zh-cn");

            uploadRequest.Headers.Add("Accept-Encoding","gzip, deflate");

            uploadRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;

            //uploadRequest.Headers["Cookie"] = cookie;//上传文件时需要的cookies

            //创建一个内存流Stream memStream =new MemoryStream();

            boundary ="--"+ boundary;

            //添加上传文件参数格式边界stringparamFormat = boundary +"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}\r\n";

            NameValueCollection param =new NameValueCollection();

            param.Add("fname", dataName);//写上参数foreach(stringkeyin param.Keys)

            {

                stringformitem =string.Format(paramFormat, key, param[key]);

                byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);

                memStream.Write(formitembytes, 0, formitembytes.Length);

            }

            //添加上传文件数据格式边界stringdataFormat = boundary +"\r\nContent-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\nContent-Type:application/octet-stream\r\n\r\n";

            stringheader =string.Format(dataFormat, dataName, dataName);byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);

            memStream.Write(headerbytes, 0, headerbytes.Length);

            memStream.Write(dataBytes, 0, dataBytes.Length);

            //添加文件结束边界byte[] boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n\n"+ boundary +"\r\nContent-Disposition: form-data; name=\"Upload\"\r\n\nSubmit Query\r\n"+ boundary +"--");

            memStream.Write(boundarybytes, 0, boundarybytes.Length);

            //设置请求长度uploadRequest.ContentLength = memStream.Length;

            //获取请求写入流Stream requestStream = uploadRequest.GetRequestStream();

            //将内存流数据读取位置归零memStream.Position =0;

            byte[] tempBuffer =newbyte[memStream.Length];

            memStream.Read(tempBuffer, 0, tempBuffer.Length);

            memStream.Close();

            //将内存流中的buffer写入到请求写入流requestStream.Write(tempBuffer,0, tempBuffer.Length);

            requestStream.Close();

            //获取到上传请求的响应HttpWebResponse response = GetResponse(uploadRequest);

            return response;

        }


2.Controller接收byte

Controller接收byte也等同于接收文件,这里的参数name是文件名称。

protectedbyte[] GetHttpBinary(string name)

        {

            if(this.Request.Files ==null||this.Request.Files.Count <=0)returnnull;

            foreach(stringkeyinthis.Request.Files.Keys)

            {

                if(key == name)

                {

                    HttpPostedFileBase httpPostedFile =this.Request.Files[key];

                    intfileContentLength = httpPostedFile.ContentLength;

                    byte[] fileBytes =newbyte[fileContentLength];

                    //创建Stream对象,并指向上传文件Stream fileStream = httpPostedFile.InputStream;

                    //从当前流中读取字节,读入字节数组中fileStream.Read(fileBytes,0, fileContentLength);

                    return fileBytes;

                }

            }

            returnnull;

        }





©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容