天天看點

byte比較_.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; using System.Runtime.Serialization.Formatters.Binary;

2、object轉byte方法
byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

public static byte[] ToBytes(object obj) { if (obj == null) return null; byte[] buff; using (MemoryStream ms = new MemoryStream()) { IFormatter iFormatter = new BinaryFormatter(); iFormatter.Serialize(ms, obj); buff = ms.GetBuffer(); } return buff; }

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法
3. byte轉object
byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

public static object ToObject(byte[] bytes) { if (bytes == null) return null; object obj; using (MemoryStream ms = new MemoryStream(bytes)) { IFormatter iFormatter = new BinaryFormatter(); obj = iFormatter.Deserialize(ms); } return obj; }

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法
二、使用SharpZipLib進行GZip壓縮和解壓

經過反複實作修改,我感覺用開源類庫ICSharpCode.SharpZipLib進行GZip壓縮解壓比.NET自帶的System.IO.Compression.GZipStream效果更好。自己感覺,資料讀取成DataTable壓縮,不如把DataTable轉化為實體類清單進行壓縮效果好。

ICSharpCode.SharpZipLib你可以很容易從網絡上擷取到。

如果發送方對資料進行GZip壓縮,接收方必須要對資料進行GZip解壓。

1、導入命名空間

using ICSharpCode.SharpZipLib.GZip; using System.IO;

2.GZip壓縮
byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

public static byte[] 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; }

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法
3.GZip解壓
byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

private const int BUFFER_LENGTH = 2048; public static byte[] 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(); int size = 0; byte[] buffer = new byte[BUFFER_LENGTH]; while ((size = s.Read(buffer, 0, buffer.Length)) > 0) { o.Write(buffer, 0, size); } } } bytes = o.ToArray(); } return bytes; }

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

三、Controller發送byte和控制台程式接收byte

1.Controller發送byte

在.NET MVC的

Controller類中發送資料很簡單,用

Response進行如下發送就可以了,當然事先要把資料轉化成byte,可以壓縮也可以不壓縮;但是這裡的ContentType 内容表明這個資料是經過GZip壓縮的。

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

private void SendBytes(byte[] bytes) { Response.ClearContent(); Response.ContentType = "application/x-zip-compressed";//發送的是gzip格式 Response.BinaryWrite(bytes); Response.End(); }

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法
2.控制台程式接收byte

雖然說是

Controller發送byte,其實是控制台程式通路了某個url後Controller才發送資料,是以這裡用

PostBinary首先進行通路。

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

public static byte[] PostBinary(string url, string body, CookieContainer cookie) { HttpWebRequest request = CreateRequest(url, body, cookie); HttpWebResponse response = GetResponse(request); byte[] bytes = ReadAllBytes(response); return bytes; }

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法
byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

private static HttpWebRequest CreateRequest(string url, string body, CookieContainer cookie) { Encoding encoding = Encoding.UTF8; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.Accept = "text/html, application/xhtml+xml, **"; 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; //添加上傳檔案參數格式邊界 string paramFormat = boundary + "rnContent-Disposition: form-data; name="{0}";rnrn{1}rn"; NameValueCollection param = new NameValueCollection(); param.Add("fname", dataName);//寫上參數 foreach (string key in param.Keys) { string formitem = string.Format(paramFormat, key, param[key]); byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); memStream.Write(formitembytes, 0, formitembytes.Length); } //添加上傳檔案資料格式邊界 string dataFormat = boundary + "rnContent-Disposition: form-data; name="{0}";filename="{1}"rnContent-Type:application/octet-streamrnrn"; string header = 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("rnn" + boundary + "rnContent-Disposition: form-data; name="Upload"rnnSubmit Queryrn" + boundary + "--"); memStream.Write(boundarybytes, 0, boundarybytes.Length); //設定請求長度 uploadRequest.ContentLength = memStream.Length; //擷取請求寫入流 Stream requestStream = uploadRequest.GetRequestStream(); //将記憶體流資料讀取位置歸零 memStream.Position = 0; byte[] tempBuffer = new byte[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; }

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法
2.Controller接收byte

Controller接收byte也等同于接收檔案,這裡的參數name是檔案名稱。

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

protected byte[] GetHttpBinary(string name) { if (this.Request.Files == null || this.Request.Files.Count <= 0) return null; foreach (string key in this.Request.Files.Keys) { if (key == name) { HttpPostedFileBase httpPostedFile = this.Request.Files[key]; int fileContentLength = httpPostedFile.ContentLength; byte[] fileBytes = new byte[fileContentLength]; //建立Stream對象,并指向上傳檔案 Stream fileStream = httpPostedFile.InputStream; //從目前流中讀取位元組,讀入位元組數組中 fileStream.Read(fileBytes, 0, fileContentLength); return fileBytes; } } return null; }

byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法
byte比較_.NET BS端和CS端互相壓縮發送接收byte對象資料方法

繼續閱讀