.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;

        }





你可能感兴趣的:(.NET BS端和CS端相互压缩发送接收byte对象数据方法)