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 }
反序列化类
原文地址:https://www.cnblogs.com/luxishi/p/9172407.html