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;//=new ProfilterData[limitNum];
12
13     private BinaryFormatter binFormat = new BinaryFormatter();//创建二进制序列化器
14
15     public DataCache(int limitNum,string filePath)
16     {
17         _index=0;
18         _filePath=filePath;
19         _limitNum=limitNum;
20         _cacheArr=new ProfilterData[limitNum];
21         for(int i=0;i<_cacheArr.Length;i++)
22         {
23             _cacheArr[i]=new ProfilterData();
24         }
25         FileStream fStream = new FileStream(_filePath,FileMode.Create);
26         fStream.Close();
27     }
28     /// <summary>
29     /// 添加数据
30     /// </summary>
31     /// <param name="fps"></param>
32     /// <param name="memory"></param>
33     public void Append(float fps,float memory)
34     {
35         if(_index==_limitNum-1)
36         {
37             WriteData(_cacheArr);
38         }
39         ProfilterData profData=_cacheArr[_index];
40         profData.fps=fps;
41         profData.memory=memory;
42         _index++;
43     }
44
45
46     /// <summary>
47     /// 立即结算
48     /// </summary>
49     public void SettleAtOnce()
50     {
51         if(_index==0)
52         return;
53
54         ProfilterData [] tempArr=new ProfilterData[_index];
55         for(int i=0;i<tempArr.Length;i++)
56         {
57             tempArr[i]=_cacheArr[i];
58         }
59         WriteData(tempArr);
60     }
61
62     /// <summary>
63     /// 写入数据
64     /// </summary>
65     private void WriteData(ProfilterData [] arr)
66     {
67         using (FileStream fStream = new FileStream(_filePath,FileMode.Append,FileAccess.Write))
68         {
69             binFormat.Serialize(fStream, arr);
70             fStream.Close();
71         }
72         _index=0;
73     }
74 }

序列化类

 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         }
27         return profList;
28     }
29 }

反序列化类

原文地址:https://www.cnblogs.com/luxishi/p/9172407.html

时间: 2024-10-18 18:04:02

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

Android 序列化对象接口Parcelable使用方法

什么是Parcelable ? Parcelable,定义了将数据写入Parcel,和从Parcel中读出的接口.一个实体(用类来表示),如果需要封装到消息中去,就必须实现这一接口,实现了这一接口,该实体就成为"可打包的"了. Parcelable 传递对象 Android序列化对象主要有两种方法: 1.实现Serializable接口,实现Serializable接口是JavaSE本身就支持的; 2.实现Parcelable接口,Parcelable是Android特有的功能,效率比

每天进步一点点-序列化和反序列(将对象写入硬盘文件and从硬盘文件读出对象)

一个类如果实现了Serializable接口,那么这个类创建的对象就是所谓序列化的对象.所谓"对象序列化": 简单一句话:使用它可以象存储文本或者数字一样简单的存储对象.一个应用是,程序在执行过程中突然遇到短电或者其他的故障导致程序终止,那么对象当前的工作状态也就会丢失,这对于有些应用来说是可怕的.用对象序列化就可以解决这个问题,因为它可以将对象的全部内容保存于磁盘的文件,这样对象执行状态也就被存储了,到需要时还可以将其从文件中按原样再读取出来,这样就解决了数据丢失问题.对象序列化可以

C#序列化多个对象到单个文件

特定的情况下,可能需要将多个对象保存到文件中.在网上找了一阵,没发现专门说这个问题的.在博问看到了一个相关的问题和回答,整理了一下.以下是我的一个简单实现: //测试用于保存的类 [Serializable] class TestToSerizable { int i; string b; public TestToSerizable(int i, string b) { this.i = i; this.b = b; } } class Program { static void Main(s

Android中Serializable和Parcelable序列化对象详解

学习内容: 1.序列化的目的 2.Android中序列化的两种方式 3.Parcelable与Serializable的性能比较 4.Android中如何使用Parcelable进行序列化操作 5.Parcelable的工作原理 6.相关实例 1.序列化的目的 (1).永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中 (2).通过序列化操作将对象数据在网络上进行传输(由于网络传输是以字节流的方式对数据进行传输的.因此序列化的目的是将对象数据转换成字节流的形式) (3).将对象数据在进程

使用XML序列化器生成XML文件和利用pull解析XML文件

首先,指定XML格式,我指定的XML格式如下: <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <message> <sms> <body> 陈驰0 </body> <date> 1462162910995 </date> <address> 1380 </address> <type> 1 </type> &

Android中序列化对象到XMl 和 XML反序列化为对象

package com.example.xmloperation; import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import java.util.Random; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; imp

Hessian RPC示例和基于Http请求的Hessian序列化对象传输

本文主要介绍两个案例,第一个是使用Hessian来实现远程过程调用,第二个是通过Hessian提供的二进制RPC协议进行和Servlet进行数据交互,Hessian本身即是基于Http的RPC实现. 案例一: 1.准备工作 这里建立一个Maven项目,其中包含四个模块,父模块(仅用来聚合其它模块,不做实际使用),服务器端模块,客户端模块,API模块(远程过程接口,供服务器和客户端使用).目录结构见下图: 2.添加Hessian的依赖 由于客户端和服务器都要依赖Hessian的包,这里可以添加到父

序列化对象

实现Serialiable 接口才能进行序列化 import java.io.Serializable; class Customer implements Serializable { private String name; private int age; public Customer(String name, int age) { this.name = name; this.age = age; } public String toString() { return "name=&q

C# 调用Webservice并传递序列化对象

原文:C# 调用Webservice并传递序列化对象 C#动态调用WebService注意要点 1.动态调用的url后面注意一定要加上?WSDL   例如:string _url = "http://服务器IP:端口/CITI_TRANS_WH/wsTransData_InWH.asmx?WSDL"; ---------------------------------------------------------------------------------------------