-
C# .NET的BinaryFormatter、protobuf-net、Newtonsoft.Json以及自己写的序列化方法序列化效
测试数据使用的是项目中的真实数据,每条数据28个字段,数据量126215条数据
测试数据库Oracle 11g
测试电脑性能:ThinkPad T490,CPU是i5-8265U,全核睿频约3.2GHz,单核睿频3.7GHz,硬盘是500G固态硬盘
实体类代码:
BusinessEntity代码:

using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace Models { [Serializable] [DataContract(IsReference = true, Namespace = "http://www.suncreate.net/2014/combatplatform")] public abstract class BusinessEntity { protected BusinessEntity(string platformName) { } [DataMember] public virtual string PlatformName { get; set; } } }
PtCameraInfo代码:

using System; using System.ComponentModel; using System.Runtime.Serialization; using System.Text; using Utils; namespace Models { [Serializable] [DataContract(IsReference = true)] public partial class PtCameraInfo : BusinessEntity, INotifyPropertyChanging, INotifyPropertyChanged { private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(System.String.Empty); private string _ID; private string _CAMERA_NO; private string _GBNO; private string _CAMERA_NAME; private System.Nullable<decimal> _ORG_ID; private string _LONGITUDE; private string _LATITUDE; private string _CAMERA_DIRECTION; private System.Nullable<decimal> _CAMERA_TYPE; private string _CAMERA_STATE; private System.Nullable<decimal> _IS_HAVE_CONSOLE; private string _SHORT_MSG; private string _IS_WIFI; private int _BuildPeriod; private int _KeyUnit; private string _Street; private int _CAMERA_FUN_TYPE; private int _IMPORT_WATCH; private string _ANALYSIS_NO; private string _Camera_Ip; private string _PLATFORM_PRODUCT_ID; private int? _RECODE_SAVE_TYPE; private string _CAMERA_BELONGS_ID; private string _CAMERA_BELONGS_PK; private string _POSITION_TYPE; private DateTime _MODIFY_TIME; private int? _IS_DEL; private string _Monitor_Type; #region Extensibility Method Definitions partial void OnCreated(); #endregion public new const string PlatformName = "CameraInfo"; public PtCameraInfo(string strPlatformName) : base(strPlatformName) { OnCreated(); } public PtCameraInfo() : base(PlatformName) { OnCreated(); } /// <summary> /// There are no comments for ID in the schema. /// </summary> [DataMember(Order = 1)] public virtual string ID { get { return this._ID; } set { if (this._ID != value) { this.SendPropertyChanging(); this._ID = value; this.SendPropertyChanged("ID"); } } } /// <summary> /// There are no comments for CAMERA_NO in the schema. /// </summary> [DataMember(Order = 2)] public virtual string CAMERA_NO { get { return this._CAMERA_NO; } set { if (this._CAMERA_NO != value) { this.SendPropertyChanging(); this._CAMERA_NO = value; this.SendPropertyChanged("CAMERA_NO"); } } } /// <summary> /// There are no comments for CAMERA_NAME in the schema. /// </summary> [DataMember(Order = 3)] public virtual string CAMERA_NAME { get { return this._CAMERA_NAME; } set { if (this._CAMERA_NAME != value) { this.SendPropertyChanging(); this._CAMERA_NAME = value; this.SendPropertyChanged("CAMERA_NAME"); } } } /// <summary> /// There are no comments for ORG_ID in the schema. /// </summary> [DataMember(Order = 4)] public virtual System.Nullable<decimal> ORG_ID { get { return this._ORG_ID; } set { if (this._ORG_ID != value) { this.SendPropertyChanging(); this._ORG_ID = value; this.SendPropertyChanged("ORG_ID"); } } } /// <summary> /// There are no comments for LONGITUDE in the schema. /// </summary> [DataMember(Order = 5)] public virtual string LONGITUDE { get { return this._LONGITUDE; } set { if (this._LONGITUDE != value) { this.SendPropertyChanging(); this._LONGITUDE = value; this.SendPropertyChanged("LONGITUDE"); } } } /// <summary> /// There are no comments for LATITUDE in the schema. /// </summary> [DataMember(Order = 6)] public virtual string LATITUDE { get { return this._LATITUDE; } set { if (this._LATITUDE != value) { this.SendPropertyChanging(); this._LATITUDE = value; this.SendPropertyChanged("LATITUDE"); } } } /// <summary> /// There are no comments for CAMERA_DIRECTION in the schema. /// </summary> [DataMember(Order = 7)] public virtual string CAMERA_DIRECTION { get { return this._CAMERA_DIRECTION; } set { if (this._CAMERA_DIRECTION != value) { this.SendPropertyChanging(); this._CAMERA_DIRECTION = value; this.SendPropertyChanged("CAMERA_DIRECTION"); } } } /// <summary> /// There are no comments for CAMERA_TYPE in the schema. /// </summary> [DataMember(Order = 8)] public virtual System.Nullable<decimal> CAMERA_TYPE { get { return this._CAMERA_TYPE; } set { if (this._CAMERA_TYPE != value) { this.SendPropertyChanging(); this._CAMERA_TYPE = value; this.SendPropertyChanged("CAMERA_TYPE"); } } } /// <summary> /// There are no comments for CAMERA_STATE in the schema. /// </summary> [DataMember(Order = 9)] public virtual string CAMERA_STATE { get { return this._CAMERA_STATE; } set { if (this._CAMERA_STATE != value) { this.SendPropertyChanging(); this._CAMERA_STATE = value; this.SendPropertyChanged("CAMERA_STATE"); //this.SendPropertyChanged(this); } } } /// <summary> /// There are no comments for IS_HAVE_CONSOLE in the schema. /// </summary> [DataMember(Order = 10)] public virtual System.Nullable<decimal> IS_HAVE_CONSOLE { get { return this._IS_HAVE_CONSOLE; } set { if (this._IS_HAVE_CONSOLE != value) { this.SendPropertyChanging(); this._IS_HAVE_CONSOLE = value; this.SendPropertyChanged("IS_HAVE_CONSOLE"); } } } [DataMember(Order = 11)] public virtual string SHORT_MSG { get { return this._SHORT_MSG; } set { if (this._SHORT_MSG != value) { this.SendPropertyChanging(); this._SHORT_MSG = value; this.SendPropertyChanged("SHORT_MSG"); } } } /// <summary> /// 设备ip /// </summary> [DataMember(Order = 12)] public virtual string Camera_Ip { get { return this._Camera_Ip; } set { if (this._Camera_Ip != value) { this.SendPropertyChanging(); this._Camera_Ip = value; this.SendPropertyChanged("Camera_Ip"); } } } /// <summary> /// WIFI探针 /// </summary> [DataMember(Order = 13)] public virtual string IS_WIFI { get { return this._IS_WIFI; } set { if (this._IS_WIFI != value) { this.SendPropertyChanging(); this._IS_WIFI = value; this.SendPropertyChanged("IS_WIFI"); } } } /// <summary> /// 0全部 1天网 2雪亮 6支网 /// </summary> [DataMember(Order = 14)] public virtual int BuildPeriod { get { return this._BuildPeriod; } set { if (this._BuildPeriod != value) { this.SendPropertyChanging(); this._BuildPeriod = value; this.SendPropertyChanged("BuildPeriod"); } } } /// <summary> /// 重点单位 /// </summary> [DataMember(Order = 15)] public virtual int KeyUnit { get { return this._KeyUnit; } set { if (this._KeyUnit != value) { this.SendPropertyChanging(); this._KeyUnit = value; this.SendPropertyChanged("KeyUnit"); } } } /// <summary> /// 重点街道 /// </summary> [DataMember(Order = 16)] public virtual string Street { get { return this._Street; } set { if (this._Street != value) { this.SendPropertyChanging(); this._Street = value; this.SendPropertyChanged("Street"); } } } /// <summary> /// 1、 车辆卡口; 2、 人员卡口;3、 微卡口;4、WIFI采集;5、综合治理枪;6、 综合治理球; 7、人脸摄像机(后智能);8、虚拟卡口;9、高点监控(球);10、高点监控(枪);11、视频结构化(后智能);99、其他。可以多选,各参数以“ /” 分隔(天网:CAMERA_USE) /// </summary> [DataMember(Order = 17)] public virtual int CAMERA_FUN_TYPE { get { return this._CAMERA_FUN_TYPE; } set { if (this._CAMERA_FUN_TYPE != value) { this.SendPropertyChanging(); this._CAMERA_FUN_TYPE = value; this.SendPropertyChanged("CAMERA_FUN_TYPE"); } } } /// <summary> /// 1、第一道防控圈;2、第二道防控圈;3、第三道防空圈;4、第四道防控圈;5、第五道防控圈;6、第六道防控圈;99、其他(天网:重点监控对象) /// </summary> [DataMember(Order = 18)] public virtual int IMPORT_WATCH { get { return this._IMPORT_WATCH; } set { if (this._IMPORT_WATCH != value) { this.SendPropertyChanging(); this._IMPORT_WATCH = value; this.SendPropertyChanged("IMPORT_WATCH"); } } } /// <summary> /// 解析编码 /// </summary> [DataMember(Order = 19)] public virtual string ANALYSIS_NO { get { return this._ANALYSIS_NO; } set { if (this._ANALYSIS_NO != value) { this.SendPropertyChanging(); this._ANALYSIS_NO = value; this.SendPropertyChanged("ANALYSIS_NO"); } } } /// <summary> /// 国标编码 /// </summary> [DataMember(Order = 20)] public virtual string GBNO { get { return this._GBNO; } set { if (this._GBNO != value) { this.SendPropertyChanging(); this._GBNO = value; this.SendPropertyChanged("GBNO"); } } } /// <summary> /// 相机产品编号 /// </summary> [DataMember(Order = 21)] public virtual string PLATFORM_PRODUCT_ID { get { return this._PLATFORM_PRODUCT_ID; } set { if (this._PLATFORM_PRODUCT_ID != value) { this.SendPropertyChanging(); this._PLATFORM_PRODUCT_ID = value; this.SendPropertyChanged("PLATFORM_PRODUCT_ID"); } } } /// <summary> /// There are no comments for CAMERA_NO in the schema. /// </summary> [DataMember(Order = 22)] public virtual int? RECODE_SAVE_TYPE { get { return this._RECODE_SAVE_TYPE; } set { if (this._RECODE_SAVE_TYPE != value) { this.SendPropertyChanging(); this._RECODE_SAVE_TYPE = value; this.SendPropertyChanged("RECODE_SAVE_TYPE"); } } } /// <summary> /// 实卡编码 /// </summary> [DataMember(Order = 23)] public virtual string CAMERA_BELONGS_ID { get { return this._CAMERA_BELONGS_ID; } set { if (this._CAMERA_BELONGS_ID != value) { this.SendPropertyChanging(); this._CAMERA_BELONGS_ID = value; this.SendPropertyChanged("CAMERA_BELONGS_ID"); } } } /// <summary> /// 虚卡编码 /// </summary> [DataMember(Order = 24)] public virtual string CAMERA_BELONGS_PK { get { return this._CAMERA_BELONGS_PK; } set { if (this._CAMERA_BELONGS_PK != value) { this.SendPropertyChanging(); this._CAMERA_BELONGS_PK = value; this.SendPropertyChanged("CAMERA_BELONGS_PK"); } } } /// <summary> /// 位置类型 /// </summary> [DataMember(Order = 25)] public virtual string POSITION_TYPE { get { return this._POSITION_TYPE; } set { if (this._POSITION_TYPE != value) { this.SendPropertyChanging(); this._POSITION_TYPE = value; this.SendPropertyChanged("POSITION_TYPE"); } } } /// <summary> /// 时间戳 /// </summary> [DataMember(Order = 26)] public virtual DateTime MODIFY_TIME { get { return this._MODIFY_TIME; } set { if (this._MODIFY_TIME != value) { this.SendPropertyChanging(); this._MODIFY_TIME = value; this.SendPropertyChanged("MODIFY_TIME"); } } } /// <summary> /// 是否删除 /// </summary> [DataMember(Order = 27)] public virtual int? IS_DEL { get { return this._IS_DEL; } set { if (this._IS_DEL != value) { this.SendPropertyChanging(); this._IS_DEL = value; this.SendPropertyChanged("IS_DEL"); } } } /// <summary> /// 监控点位类型 /// </summary> [DataMember(Order = 28)] public virtual string Monitor_Type { get { return this._Monitor_Type; } set { if (this._Monitor_Type != value) { this.SendPropertyChanging(); this._Monitor_Type = value; this.SendPropertyChanged("Monitor_Type"); } } } public virtual event PropertyChangingEventHandler PropertyChanging; public virtual event PropertyChangedEventHandler PropertyChanged; protected virtual void SendPropertyChanging() { var handler = this.PropertyChanging; if (handler != null) handler(this, emptyChangingEventArgs); } protected virtual void SendPropertyChanging(System.String propertyName) { var handler = this.PropertyChanging; if (handler != null) handler(this, new PropertyChangingEventArgs(propertyName)); } protected virtual void SendPropertyChanged(System.String propertyName) { var handler = this.PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append(this.ID + "}{"); sb.Append(this.CAMERA_NO + "}{"); sb.Append(this.GBNO + "}{"); sb.Append(this.CAMERA_NAME + "}{"); sb.Append(this.ORG_ID + "}{"); sb.Append(this.LONGITUDE + "}{"); sb.Append(this.LATITUDE + "}{"); sb.Append(this.CAMERA_DIRECTION + "}{"); sb.Append(this.CAMERA_TYPE + "}{"); sb.Append(this.CAMERA_STATE + "}{"); sb.Append(this.IS_HAVE_CONSOLE + "}{"); sb.Append(this.SHORT_MSG + "}{"); sb.Append(this.IS_WIFI + "}{"); sb.Append(this.BuildPeriod + "}{"); sb.Append(this.KeyUnit + "}{"); sb.Append(this.Street + "}{"); sb.Append(this.CAMERA_FUN_TYPE + "}{"); sb.Append(this.IMPORT_WATCH + "}{"); sb.Append(this.ANALYSIS_NO + "}{"); sb.Append(this.Camera_Ip + "}{"); sb.Append(this.PLATFORM_PRODUCT_ID + "}{"); sb.Append(this.RECODE_SAVE_TYPE + "}{"); sb.Append(this.CAMERA_BELONGS_ID + "}{"); sb.Append(this.CAMERA_BELONGS_PK + "}{"); sb.Append(this.POSITION_TYPE + "}{"); sb.Append(this.MODIFY_TIME + "}{"); sb.Append(this.IS_DEL + "}{"); sb.Append(this.Monitor_Type + "}{"); return sb.ToString(); } public static PtCameraInfo FromString(string value) { PtCameraInfo info = new PtCameraInfo(); string[] strArr = value.Split(new string[] { "}{" }, StringSplitOptions.None); info.ID = strArr[0]; info.CAMERA_NO = strArr[1]; info.GBNO = strArr[2]; info.CAMERA_NAME = strArr[3]; info.ORG_ID = StringUtil.ConvertToDecimal(strArr[4]); info.LONGITUDE = strArr[5]; info.LATITUDE = strArr[6]; info.CAMERA_DIRECTION = strArr[7]; info.CAMERA_TYPE = StringUtil.ConvertToDecimal(strArr[8]); info.CAMERA_STATE = strArr[9]; info.IS_HAVE_CONSOLE = StringUtil.ConvertToDecimal(strArr[10]); info.SHORT_MSG = strArr[11]; info.IS_WIFI = strArr[12]; info.BuildPeriod = StringUtil.ConvertToInt32(strArr[13]); info.KeyUnit = StringUtil.ConvertToInt32(strArr[14]); info.Street = strArr[15]; info.CAMERA_FUN_TYPE = StringUtil.ConvertToInt32(strArr[16]); info.IMPORT_WATCH = StringUtil.ConvertToInt32(strArr[17]); info.ANALYSIS_NO = strArr[18]; info.Camera_Ip = strArr[19]; info.PLATFORM_PRODUCT_ID = strArr[20]; info.RECODE_SAVE_TYPE = StringUtil.ConvertToInt32(strArr[21]); info.CAMERA_BELONGS_ID = strArr[22]; info.CAMERA_BELONGS_PK = strArr[23]; info.POSITION_TYPE = strArr[24]; info.MODIFY_TIME = StringUtil.ConvertToDateTime(strArr[25]).Value; info.IS_DEL = Convert.ToInt32(strArr[26]); info.Monitor_Type = strArr[27]; return info; } } }
自写简单序列化方法部分代码:
序列化:

using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { fs.SetLength(0); using (StreamWriter sw = new StreamWriter(fs)) { StringBuilder str = new StringBuilder(); foreach (PtCameraInfo item in value) { str.Append(item.ToString() + "]["); } sw.Write(str); } fs.Close(); }
反序列化:

using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { using (StreamReader sr = new StreamReader(fs)) { LogUtil.Log("自写序列化后文件大小:" + (fs.Length / 1024.0 / 1024.0).ToString("0.000" + "M")); string str = sr.ReadToEnd(); string[] modelArr = str.Split(new string[] { "][" }, StringSplitOptions.RemoveEmptyEntries); List<PtCameraInfo> result = new List<Models.PtCameraInfo>(); foreach (string modelStr in modelArr) { PtCameraInfo info = PtCameraInfo.FromString(modelStr); result.Add(info); } return result; } }
PtCameraInfo类的ToString和FromString方法:

public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append(this.ID + "}{"); sb.Append(this.CAMERA_NO + "}{"); sb.Append(this.GBNO + "}{"); sb.Append(this.CAMERA_NAME + "}{"); sb.Append(this.ORG_ID + "}{"); sb.Append(this.LONGITUDE + "}{"); sb.Append(this.LATITUDE + "}{"); sb.Append(this.CAMERA_DIRECTION + "}{"); sb.Append(this.CAMERA_TYPE + "}{"); sb.Append(this.CAMERA_STATE + "}{"); sb.Append(this.IS_HAVE_CONSOLE + "}{"); sb.Append(this.SHORT_MSG + "}{"); sb.Append(this.IS_WIFI + "}{"); sb.Append(this.BuildPeriod + "}{"); sb.Append(this.KeyUnit + "}{"); sb.Append(this.Street + "}{"); sb.Append(this.CAMERA_FUN_TYPE + "}{"); sb.Append(this.IMPORT_WATCH + "}{"); sb.Append(this.ANALYSIS_NO + "}{"); sb.Append(this.Camera_Ip + "}{"); sb.Append(this.PLATFORM_PRODUCT_ID + "}{"); sb.Append(this.RECODE_SAVE_TYPE + "}{"); sb.Append(this.CAMERA_BELONGS_ID + "}{"); sb.Append(this.CAMERA_BELONGS_PK + "}{"); sb.Append(this.POSITION_TYPE + "}{"); sb.Append(this.MODIFY_TIME + "}{"); sb.Append(this.IS_DEL + "}{"); sb.Append(this.Monitor_Type + "}{"); return sb.ToString(); } public static PtCameraInfo FromString(string value) { PtCameraInfo info = new PtCameraInfo(); string[] strArr = value.Split(new string[] { "}{" }, StringSplitOptions.None); info.ID = strArr[0]; info.CAMERA_NO = strArr[1]; info.GBNO = strArr[2]; info.CAMERA_NAME = strArr[3]; info.ORG_ID = StringUtil.ConvertToDecimal(strArr[4]); info.LONGITUDE = strArr[5]; info.LATITUDE = strArr[6]; info.CAMERA_DIRECTION = strArr[7]; info.CAMERA_TYPE = StringUtil.ConvertToDecimal(strArr[8]); info.CAMERA_STATE = strArr[9]; info.IS_HAVE_CONSOLE = StringUtil.ConvertToDecimal(strArr[10]); info.SHORT_MSG = strArr[11]; info.IS_WIFI = strArr[12]; info.BuildPeriod = StringUtil.ConvertToInt32(strArr[13]); info.KeyUnit = StringUtil.ConvertToInt32(strArr[14]); info.Street = strArr[15]; info.CAMERA_FUN_TYPE = StringUtil.ConvertToInt32(strArr[16]); info.IMPORT_WATCH = StringUtil.ConvertToInt32(strArr[17]); info.ANALYSIS_NO = strArr[18]; info.Camera_Ip = strArr[19]; info.PLATFORM_PRODUCT_ID = strArr[20]; info.RECODE_SAVE_TYPE = StringUtil.ConvertToInt32(strArr[21]); info.CAMERA_BELONGS_ID = strArr[22]; info.CAMERA_BELONGS_PK = strArr[23]; info.POSITION_TYPE = strArr[24]; info.MODIFY_TIME = StringUtil.ConvertToDateTime(strArr[25]).Value; info.IS_DEL = Convert.ToInt32(strArr[26]); info.Monitor_Type = strArr[27]; return info; }
测试代码:

private void TestSerialize() { Task.Factory.StartNew(() => { try { Log("开始"); LogUtil.Log("开始"); string sql = "select * from PT_CAMERA_INFO"; string connStr = "Data Source=(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = orcl)));Persist Security Info=True;User Id=shiny;Password=shiny;"; DataTable dt = new DataTable(); using (OracleConnection conn = new OracleConnection(connStr)) { conn.Open(); OracleDataAdapter command = new OracleDataAdapter(sql, conn); command.Fill(dt); } LogUtil.Log("数据量:" + dt.Rows.Count); int n = dt.Rows.Count; List<PtCameraInfo> list = new List<PtCameraInfo>(); for (int i = 0; i < n; i++) { DataRow dataRow = dt.Rows[i]; PtCameraInfo info = new PtCameraInfo(); info.ID = StringUtil.ConvertToString(dataRow[0]); info.CAMERA_NO = StringUtil.ConvertToString(dataRow[1]); info.GBNO = StringUtil.ConvertToString(dataRow[2]); info.CAMERA_NAME = StringUtil.ConvertToString(dataRow[3]); info.ORG_ID = StringUtil.ConvertToDecimal(dataRow[4]); info.LONGITUDE = StringUtil.ConvertToString(dataRow[5]); info.LATITUDE = StringUtil.ConvertToString(dataRow[6]); info.CAMERA_DIRECTION = StringUtil.ConvertToString(dataRow[7]); info.CAMERA_TYPE = StringUtil.ConvertToDecimal(dataRow[8]); info.CAMERA_STATE = StringUtil.ConvertToString(dataRow[9]); info.IS_HAVE_CONSOLE = StringUtil.ConvertToDecimal(dataRow[10]); info.SHORT_MSG = StringUtil.ConvertToString(dataRow[11]); info.IS_WIFI = StringUtil.ConvertToString(dataRow[12]); info.BuildPeriod = StringUtil.ConvertToInt32_2(dataRow[13]); info.KeyUnit = StringUtil.ConvertToInt32_2(dataRow[14]); info.Street = StringUtil.ConvertToString(dataRow[15]); info.CAMERA_FUN_TYPE = StringUtil.ConvertToInt32_2(dataRow[16]); info.IMPORT_WATCH = StringUtil.ConvertToInt32_2(dataRow[17]); info.ANALYSIS_NO = StringUtil.ConvertToString(dataRow[18]); info.Camera_Ip = StringUtil.ConvertToString(dataRow[19]); info.PLATFORM_PRODUCT_ID = StringUtil.ConvertToString(dataRow[20]); info.RECODE_SAVE_TYPE = StringUtil.ConvertToInt32(dataRow[21]); info.CAMERA_BELONGS_ID = StringUtil.ConvertToString(dataRow[22]); info.CAMERA_BELONGS_PK = StringUtil.ConvertToString(dataRow[23]); info.POSITION_TYPE = StringUtil.ConvertToString(dataRow[24]); info.MODIFY_TIME = StringUtil.ConvertToDateTime(dataRow[25]) == null ? DateTime.MinValue : StringUtil.ConvertToDateTime(dataRow[25]).Value; info.IS_DEL = StringUtil.ConvertToInt32_2(dataRow[26]); info.Monitor_Type = StringUtil.ConvertToString(dataRow[27]); list.Add(info); } LogTimeUtil logTimeUtil = new LogTimeUtil(); FileCacheUtil.SetValue("list1", list); logTimeUtil.LogTime("BinaryFormatter写list1"); LogTimeUtil logTimeUtil2 = new LogTimeUtil(); FileCacheUtil2.SetValue("list2", list); logTimeUtil2.LogTime("ProtoBuf写list2"); LogTimeUtil logTimeUtil3 = new LogTimeUtil(); FileCacheUtil3.SetValue("list3", list); logTimeUtil3.LogTime("Newtonsoft.Json写list3"); LogTimeUtil logTimeUtil4 = new LogTimeUtil(); FileCacheUtil4.SetValue("list4", list); logTimeUtil4.LogTime("自写序列化方法写list4"); LogTimeUtil logTimeUtil5 = new LogTimeUtil(); List<PtCameraInfo> result1 = (List<PtCameraInfo>)FileCacheUtil.GetValue("list1"); logTimeUtil5.LogTime("BinaryFormatter读list1"); LogTimeUtil logTimeUtil6 = new LogTimeUtil(); List<PtCameraInfo> result2 = FileCacheUtil2.GetValue<List<PtCameraInfo>>("list2"); logTimeUtil6.LogTime("ProtoBuf读list2"); LogTimeUtil logTimeUtil7 = new LogTimeUtil(); List<PtCameraInfo> result3 = (List<PtCameraInfo>)FileCacheUtil3.GetValue("list3"); logTimeUtil7.LogTime("Newtonsoft.Json读list3"); LogTimeUtil logTimeUtil8 = new LogTimeUtil(); List<PtCameraInfo> result4 = FileCacheUtil4.GetValue("list4"); logTimeUtil8.LogTime("自写序列化方法读list4"); LogUtil.Log("结束"); Log("结束"); } catch (Exception ex) { Log("错误:" + ex.Message + "\r\n" + ex.StackTrace); } }); }
FileCacheUtil.cs代码:

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization.Formatters.Binary; using System.Threading; using System.Reflection; namespace Utils { /// <summary> /// 缓存工具类 /// 缓存数据存储在文件中 /// </summary> public static class FileCacheUtil { #region 变量 /// <summary> /// 锁 /// </summary> private static object _lock = new object(); private static BinaryFormatter formatter = new BinaryFormatter(); private static string _folderPath; #endregion #region 静态构造函数 static FileCacheUtil() { UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase); _folderPath = Path.GetDirectoryName(Uri.UnescapeDataString(uri.Path)) + "\\cache"; } #endregion #region SetValue 保存键值对 /// <summary> /// 保存键值对 /// </summary> public static void SetValue(string key, object value, string dependentKey = null, int expirationMinutes = 0) { try { DateTime dt = DateTime.Now; CacheData data = new CacheData(key, value); data.updateTime = DateTime.Now; data.expirationMinutes = expirationMinutes; data.dependentKey = dependentKey; if (!Directory.Exists(_folderPath)) { Directory.CreateDirectory(_folderPath); } string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { fs.SetLength(0); formatter.Serialize(fs, data); fs.Close(); } } //LogUtil.Log("FileCacheUtil写缓存" + key + "花费时间" + DateTime.Now.Subtract(dt).TotalSeconds.ToString() + "秒"); } catch (Exception ex) { LogUtil.Error(ex, "FileCacheUtil写缓存错误"); } } #endregion #region GetValue 获取键值对 /// <summary> /// 获取键值对 /// </summary> public static object GetValue(string key) { try { DateTime dt = DateTime.Now; string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { if (File.Exists(path)) { using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { LogUtil.Log("BinaryFormatter序列化后文件大小:" + (fs.Length / 1024.0 / 1024.0).ToString("0.000"+"M")); CacheData data = (CacheData)formatter.Deserialize(fs); fs.Close(); if (data.expirationMinutes > 0 && DateTime.Now.Subtract(data.updateTime).TotalMinutes > data.expirationMinutes) { File.Delete(path); return null; } if (data.dependentKey != null) { string dependentPath = _folderPath + "\\" + GetMD5(data.dependentKey) + ".txt"; if (File.Exists(dependentPath)) { FileInfo fileInfo = new FileInfo(dependentPath); if (fileInfo.LastWriteTime > data.updateTime) { File.Delete(path); return null; } } } //LogUtil.Log("FileCacheUtil读缓存" + key + "花费时间" + DateTime.Now.Subtract(dt).TotalSeconds.ToString() + "秒"); return data.value; } } } return null; } catch (Exception ex) { LogUtil.Error(ex, "FileCacheUtil读缓存错误"); return null; } } #endregion #region Delete 删除 /// <summary> /// 删除 /// </summary> public static void Delete(string key) { string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { File.Delete(path); } } #endregion #region DeleteAll 全部删除 /// <summary> /// 全部删除 /// </summary> public static void DeleteAll() { string[] files = Directory.GetFiles(_folderPath); lock (_lock) { foreach (string file in files) { File.Delete(file); } } } #endregion #region 计算MD5值 /// <summary> /// 计算MD5值 /// </summary> private static string GetMD5(string value) { return value; string base64 = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(value)).Replace("/", "-"); if (base64.Length > 200) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] bArr = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value)); StringBuilder sb = new StringBuilder(); foreach (byte b in bArr) { sb.Append(b.ToString("x2")); } return sb.ToString(); } return base64; } #endregion } #region CacheData 缓存数据 /// <summary> /// 缓存数据 /// </summary> [Serializable] public class CacheData { /// <summary> /// 键 /// </summary> public string key { get; set; } /// <summary> /// 值 /// </summary> public object value { get; set; } /// <summary> /// 缓存更新时间 /// </summary> public DateTime updateTime { get; set; } /// <summary> /// 过期时间(分钟),0表示永不过期 /// </summary> public double expirationMinutes { get; set; } /// <summary> /// 缓存依赖键 /// </summary> public string dependentKey { get; set; } public CacheData(string key, object value) { this.key = key; this.value = value; } } #endregion }
FileCacheUtil2.cs代码:

using ProtoBuf; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using Utils; namespace Utils { /// <summary> /// 缓存工具类 /// 缓存数据存储在文件中 /// </summary> public class FileCacheUtil2 { #region 变量 /// <summary> /// 锁 /// </summary> private static object _lock = new object(); private static string _folderPath; #endregion #region 静态构造函数 static FileCacheUtil2() { UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase); _folderPath = Path.GetDirectoryName(Uri.UnescapeDataString(uri.Path)) + "\\cache"; } #endregion #region SetValue 保存键值对 /// <summary> /// 保存键值对 /// </summary> public static void SetValue<T>(string key, T value, string dependentKey = null, int expirationSecond = 0) { try { DateTime dt = DateTime.Now; CacheData2<T> data = new CacheData2<T>(key, value); data.updateTime = DateTime.Now; data.expirationSecond = expirationSecond; data.dependentKey = dependentKey; if (!Directory.Exists(_folderPath)) { Directory.CreateDirectory(_folderPath); } string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { fs.SetLength(0); Serializer.Serialize<CacheData2<T>>(fs, data); fs.Close(); } } //LogUtil.Log("FileCacheUtil写缓存" + key + "花费时间" + DateTime.Now.Subtract(dt).TotalSeconds.ToString() + "秒"); } catch (Exception ex) { LogUtil.Error(ex, "FileCacheUtil写缓存错误"); } } #endregion #region GetValue 获取键值对 /// <summary> /// 获取键值对 /// </summary> public static T GetValue<T>(string key) { try { DateTime dt = DateTime.Now; string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { if (File.Exists(path)) { using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { LogUtil.Log("ProtoBuf序列化后文件大小:" + (fs.Length / 1024.0 / 1024.0).ToString("0.000" + "M")); CacheData2<T> data = (CacheData2<T>)Serializer.Deserialize<CacheData2<T>>(fs); fs.Close(); if (data.expirationSecond > 0 && DateTime.Now.Subtract(data.updateTime).TotalSeconds > data.expirationSecond) { File.Delete(path); return default(T); } if (data.dependentKey != null) { string dependentPath = _folderPath + "\\" + GetMD5(data.dependentKey) + ".txt"; if (File.Exists(dependentPath)) { FileInfo fileInfo = new FileInfo(dependentPath); if (fileInfo.LastWriteTime > data.updateTime) { File.Delete(path); return default(T); } } } //LogUtil.Log("FileCacheUtil读缓存" + key + "花费时间" + DateTime.Now.Subtract(dt).TotalSeconds.ToString() + "秒"); return data.value; } } } return default(T); } catch (Exception ex) { LogUtil.Error(ex, "FileCacheUtil读缓存错误"); return default(T); } } #endregion #region Delete 删除 /// <summary> /// 删除 /// </summary> public static void Delete(string key) { string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { File.Delete(path); } } #endregion #region DeleteAll 全部删除 /// <summary> /// 全部删除 /// </summary> public static void DeleteAll() { string[] files = Directory.GetFiles(_folderPath); lock (_lock) { foreach (string file in files) { File.Delete(file); } } } #endregion #region 计算MD5值 /// <summary> /// 计算MD5值 /// </summary> private static string GetMD5(string value) { return value; string base64 = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(value)).Replace("/", "-"); if (base64.Length > 200) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] bArr = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value)); StringBuilder sb = new StringBuilder(); foreach (byte b in bArr) { sb.Append(b.ToString("x2")); } return sb.ToString(); } return base64; } #endregion } #region CacheData2 缓存数据 /// <summary> /// 缓存数据 /// </summary> [Serializable] [ProtoContract] public class CacheData2<T> { /// <summary> /// 键 /// </summary> [ProtoMember(1)] public string key { get; set; } /// <summary> /// 值 /// </summary> [ProtoMember(2)] public T value { get; set; } /// <summary> /// 缓存更新时间 /// </summary> [ProtoMember(3)] public DateTime updateTime { get; set; } /// <summary> /// 过期时间(秒),0表示永不过期 /// </summary> [ProtoMember(4)] public int expirationSecond { get; set; } /// <summary> /// 缓存依赖键 /// </summary> [ProtoMember(5)] public string dependentKey { get; set; } public CacheData2() { } public CacheData2(string key, T value) { this.key = key; this.value = value; } } #endregion }
FileCacheUtil3.cs代码:

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization.Formatters.Binary; using System.Threading; using System.Reflection; using Newtonsoft.Json; using Models; namespace Utils { /// <summary> /// 缓存工具类 /// 缓存数据存储在文件中 /// </summary> public static class FileCacheUtil3 { #region 变量 /// <summary> /// 锁 /// </summary> private static object _lock = new object(); private static string _folderPath; #endregion #region 静态构造函数 static FileCacheUtil3() { UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase); _folderPath = Path.GetDirectoryName(Uri.UnescapeDataString(uri.Path)) + "\\cache"; } #endregion #region SetValue 保存键值对 /// <summary> /// 保存键值对 /// </summary> public static void SetValue(string key, object value, string dependentKey = null, int expirationMinutes = 0) { try { DateTime dt = DateTime.Now; CacheData data = new CacheData(key, value); data.updateTime = DateTime.Now; data.expirationMinutes = expirationMinutes; data.dependentKey = dependentKey; if (!Directory.Exists(_folderPath)) { Directory.CreateDirectory(_folderPath); } string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { fs.SetLength(0); using (StreamWriter sw = new StreamWriter(fs)) { sw.Write(JsonConvert.SerializeObject(data)); } fs.Close(); } } // LogUtil.Log("FileCacheUtil写缓存" + key + "花费时间" + DateTime.Now.Subtract(dt).TotalSeconds.ToString() + "秒"); } catch (Exception ex) { LogUtil.Error(ex, "FileCacheUtil写缓存错误"); } } #endregion #region GetValue 获取键值对 /// <summary> /// 获取键值对 /// </summary> public static object GetValue(string key) { try { DateTime dt = DateTime.Now; string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { if (File.Exists(path)) { using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { using (StreamReader sr = new StreamReader(fs)) { LogUtil.Log("Newtonsoft.Json序列化后文件大小:" + (fs.Length / 1024.0 / 1024.0).ToString("0.000" + "M")); CacheData data = JsonConvert.DeserializeObject<CacheData>(sr.ReadToEnd()); fs.Close(); if (data.expirationMinutes > 0 && DateTime.Now.Subtract(data.updateTime).TotalMinutes > data.expirationMinutes) { File.Delete(path); return null; } if (data.dependentKey != null) { string dependentPath = _folderPath + "\\" + GetMD5(data.dependentKey) + ".txt"; if (File.Exists(dependentPath)) { FileInfo fileInfo = new FileInfo(dependentPath); if (fileInfo.LastWriteTime > data.updateTime) { File.Delete(path); return null; } } } //LogUtil.Log("FileCacheUtil读缓存" + key + "花费时间" + DateTime.Now.Subtract(dt).TotalSeconds.ToString() + "秒"); return JsonConvert.DeserializeObject<List<PtCameraInfo>>(data.value.ToString()); } } } } return null; } catch (Exception ex) { LogUtil.Error(ex, "FileCacheUtil读缓存错误"); return null; } } #endregion #region Delete 删除 /// <summary> /// 删除 /// </summary> public static void Delete(string key) { string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { File.Delete(path); } } #endregion #region DeleteAll 全部删除 /// <summary> /// 全部删除 /// </summary> public static void DeleteAll() { string[] files = Directory.GetFiles(_folderPath); lock (_lock) { foreach (string file in files) { File.Delete(file); } } } #endregion #region 计算MD5值 /// <summary> /// 计算MD5值 /// </summary> private static string GetMD5(string value) { return value; string base64 = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(value)).Replace("/", "-"); if (base64.Length > 200) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] bArr = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value)); StringBuilder sb = new StringBuilder(); foreach (byte b in bArr) { sb.Append(b.ToString("x2")); } return sb.ToString(); } return base64; } #endregion } #region CacheData 缓存数据 /// <summary> /// 缓存数据 /// </summary> [Serializable] public class CacheData3 { /// <summary> /// 键 /// </summary> public string key { get; set; } /// <summary> /// 值 /// </summary> public object value { get; set; } /// <summary> /// 缓存更新时间 /// </summary> public DateTime updateTime { get; set; } /// <summary> /// 过期时间(分钟),0表示永不过期 /// </summary> public int expirationMinutes { get; set; } /// <summary> /// 缓存依赖键 /// </summary> public string dependentKey { get; set; } public CacheData3(string key, object value) { this.key = key; this.value = value; } } #endregion }
FileCacheUtil4.cs代码:

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization.Formatters.Binary; using System.Threading; using System.Reflection; using Newtonsoft.Json; using Models; namespace Utils { /// <summary> /// 缓存工具类 /// 缓存数据存储在文件中 /// </summary> public static class FileCacheUtil4 { #region 变量 /// <summary> /// 锁 /// </summary> private static object _lock = new object(); private static string _folderPath; #endregion #region 静态构造函数 static FileCacheUtil4() { UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase); _folderPath = Path.GetDirectoryName(Uri.UnescapeDataString(uri.Path)) + "\\cache"; } #endregion #region SetValue 保存键值对 /// <summary> /// 保存键值对 /// </summary> public static void SetValue(string key, List<PtCameraInfo> value, string dependentKey = null, int expirationMinutes = 0) { try { DateTime dt = DateTime.Now; if (!Directory.Exists(_folderPath)) { Directory.CreateDirectory(_folderPath); } string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { fs.SetLength(0); using (StreamWriter sw = new StreamWriter(fs)) { StringBuilder str = new StringBuilder(); foreach (PtCameraInfo item in value) { str.Append(item.ToString() + "]["); } sw.Write(str); } fs.Close(); } } // LogUtil.Log("FileCacheUtil写缓存" + key + "花费时间" + DateTime.Now.Subtract(dt).TotalSeconds.ToString() + "秒"); } catch (Exception ex) { LogUtil.Error(ex, "FileCacheUtil写缓存错误"); } } #endregion #region GetValue 获取键值对 /// <summary> /// 获取键值对 /// </summary> public static List<PtCameraInfo> GetValue(string key) { try { DateTime dt = DateTime.Now; string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { if (File.Exists(path)) { using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { using (StreamReader sr = new StreamReader(fs)) { LogUtil.Log("自写序列化后文件大小:" + (fs.Length / 1024.0 / 1024.0).ToString("0.000" + "M")); string str = sr.ReadToEnd(); string[] modelArr = str.Split(new string[] { "][" }, StringSplitOptions.RemoveEmptyEntries); List<PtCameraInfo> result = new List<Models.PtCameraInfo>(); foreach (string modelStr in modelArr) { PtCameraInfo info = PtCameraInfo.FromString(modelStr); result.Add(info); } return result; } } } } return null; } catch (Exception ex) { LogUtil.Error(ex, "FileCacheUtil读缓存错误"); return null; } } #endregion #region Delete 删除 /// <summary> /// 删除 /// </summary> public static void Delete(string key) { string keyMd5 = GetMD5(key); string path = _folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { File.Delete(path); } } #endregion #region DeleteAll 全部删除 /// <summary> /// 全部删除 /// </summary> public static void DeleteAll() { string[] files = Directory.GetFiles(_folderPath); lock (_lock) { foreach (string file in files) { File.Delete(file); } } } #endregion #region 计算MD5值 /// <summary> /// 计算MD5值 /// </summary> private static string GetMD5(string value) { return value; string base64 = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(value)).Replace("/", "-"); if (base64.Length > 200) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] bArr = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value)); StringBuilder sb = new StringBuilder(); foreach (byte b in bArr) { sb.Append(b.ToString("x2")); } return sb.ToString(); } return base64; } #endregion } }
测试结果如下图:
测试结果整理后:
结论:
1、这几个工具中,protobuf-net序列化和反序列化效率是最快的
2、BinaryFormatter和Newtonsoft.Json反序列化慢的比较多
3、Newtonsoft.Json序列化后的文件体积比较大
4、Newtonsoft.Json在序列化反序列化过程中消耗内存较多(上图未体现,实际测试中内存占用多)
5、不出我所料,自己写的简单序列化反序列化方法也很快,为什么自己写的也很快呢?是因为使用的是最笨的方法,直接赋值,没有使用反射
6、自写序列化方法生成的文件体积也比较小,因为除了分隔符和数据内容之外,没有多余的东西,虽然分隔符很短,但是大量重复的分隔符也会占用一定的空间,所以自写的序列化方法生成的文件体积比protobuf-net要大
7、protobuf-net比BinaryFormatter反序列化快了将近一个数量级,很有实用价值
出处:https://www.cnblogs.com/s0611163/p/11872484.html