• C# 持续序列化对象追加到文件的方法


    最近有个需求,将内存和帧数数据序列化到二进制文件。为了节省内存,采用了100个对象的数组,每次存满就序列化到文件,然后归零继续存,以追加的性式继续序列化到原有文件。

    这样相当于多个数组对象存在了同一个序列化文件。反序列化的时候需要处理一下。思路是先反序列化出来一个,然后修改文件读取的Offset,继续反序列化下一个,直到文件末尾。

    1 namespace ProfilterDataNS
    2 {
    3     [Serializable]
    4     public class ProfilterData
    5     {
    6         public float fps=0;
    7         public float memory=0;
    8     }
    9 }
     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using ProfilterDataNS;
     4 using System.IO;
     5 using System.Runtime.Serialization.Formatters.Binary;
     6 
     7 public class DataCache{
     8     string _filePath="profilterData.bin";
     9     int _limitNum=100;
    10     int _index=0;
    11     ProfilterData [] _cacheArr;
    12     FileStream fStream;
    13 
    14     private BinaryFormatter binFormat = new BinaryFormatter();//创建二进制序列化器
    15     
    16     public DataCache(int limitNum,string filePath)
    17     {
    18         _index=0;
    19         _filePath=filePath;
    20         _limitNum=limitNum;
    21         _cacheArr=new ProfilterData[limitNum];
    22         for(int i=0;i<_cacheArr.Length;i++)
    23         {
    24             _cacheArr[i]=new ProfilterData();
    25         }
    26         //如果有同名旧文件存在,先覆盖一次旧文件
    27         fStream = new FileStream(_filePath,FileMode.Create);
    28         fStream.Close();
    29         fStream.Dispose();
    30         //以追加的形式
    31         fStream=new FileStream(_filePath,FileMode.Append,FileAccess.Write);
    32     }
    33     
    34     ~DataCache()
    35     {
    36         fStream.Close();
    37         fStream.Dispose();
    38     }
    39     /// <summary>
    40     /// 添加数据
    41     /// </summary>
    42     /// <param name="fps"></param>
    43     /// <param name="memory"></param>
    44     public void Append(float fps,float memory)
    45     {
    46 
    47         if(_index==_limitNum)
    48         {
    49             WriteData(_cacheArr);
    50         }
    51 
    52         ProfilterData profData=_cacheArr[_index];
    53         profData.fps=fps;
    54         profData.memory=memory;
    55         _index++;
    56     }
    57 
    58 
    59     /// <summary>
    60     /// 立即结算数据,通常在结束时调用
    61     /// </summary>
    62     public void SettleAtOnce()
    63     {
    64         if(_index!=0)
    65         {
    66             ProfilterData [] tempArr=new ProfilterData[_index];
    67             for(int i=0;i<tempArr.Length;i++)
    68             {
    69                 tempArr[i]=_cacheArr[i];
    70             }
    71             WriteData(tempArr);
    72         }
    73 
    74         fStream.Close();
    75         fStream.Dispose();
    76     }
    77 
    78     /// <summary>
    79     /// 写入数据
    80     /// </summary>
    81     private void WriteData(ProfilterData [] arr)
    82     {
    83         binFormat.Serialize(fStream, arr);
    84         _index=0;
    85     }
    86 }
    序列化类
     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using ProfilterDataNS;
     4 using System.IO;
     5 using System.Runtime.Serialization.Formatters.Binary;
     6 
     7 public class AnalyzeData{
     8     public static List<ProfilterData> Analyze(string filePath)
     9     {
    10         MemoryStream ms = new MemoryStream();
    11         BinaryFormatter binFormat = new BinaryFormatter();//创建二进制序列化器
    12 
    13         List<ProfilterData> profList=new List<ProfilterData>();
    14 
    15         using (FileStream fs= File.OpenRead("profilterData.bin"))
    16         {
    17             int offset=0;
    18             while(fs.Position<fs.Length)
    19             {
    20                 ProfilterData []dataArr=(ProfilterData[])binFormat.Deserialize(fs);
    21                 profList.AddRange(dataArr);
    22                 binFormat.Serialize(ms, dataArr);//序列化到内存流中
    23                 byte[] bt = ms.ToArray();
    24                 offset=bt.Length;//获取偏移量
    25             }
    26             fs.Close();
    27             fs.Dispose();
    28         }
    29         return profList;
    30     }
    31 }
    反序列化类
  • 相关阅读:
    mysql 权限问题
    触发器作用
    带有循环功能的存储过程
    带有条件判断的存储过程
    数据存储 三大范式-----------待续
    存储过程自 带条件判断的存储过程
    线程异步更新UI
    TextBox只能输入数字
    C#中无边框窗体移动或拖控件移动窗体
    classloader原理
  • 原文地址:https://www.cnblogs.com/luxishi/p/9172407.html
Copyright © 2020-2023  润新知