首页新闻找找看学习计划

C# 怎么序列化多个不同的对象在文件内,然后依次反序列化取出。在线等求指教

0
悬赏园豆:30 [已解决问题] 解决于 2013-08-18 17:53

有三个对象,依次用二进制方式序列化到文件中,然后依次取出来。应该怎么做,第一个对象取出来成功了,但是取第二个对象的时候出现了错误:在分析完成之前遇到了流结尾

namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
Serialize();
Deserialize();
}
static void Serialize()
{
A a = new A();
FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
BinaryWriter bw = new BinaryWriter(fs);
MemoryStream ms = new MemoryStream();
// Construct a BinaryFormatter and use it to serialize the data to the stream.
BinaryFormatter formatter = new BinaryFormatter();
try
{

formatter.Serialize(ms, a);
byte[] tem = new byte[(int)ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(tem, 0, (int)ms.Length);
bw.Write(tem);

ms.Close();
ms = new System.IO.MemoryStream();
string p = "123";
formatter.Serialize(ms, p);
byte[] tem1 = new byte[(int)ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(tem1, 0, (int)ms.Length);
bw.Seek(0, SeekOrigin.End);
bw.Write(tem1);
bw.Flush();
bw.Close();

}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
finally
{
//fs.Close();
}
}
static void Deserialize()
{
FileStream fs = new FileStream("DataFile.dat", FileMode.Open);

BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new System.IO.MemoryStream();
byte[] a = new byte[145];
fs.Read(a, 0, 145);
ms.Write(a, 0, 145);

object x = formatter.Deserialize(ms);
Console.WriteLine(x.GetType());

byte[] b = new byte[27];
fs.Seek(145, SeekOrigin.Begin);
fs.Read(b,0,27);
ms.Write(b, 0, 27);
x = formatter.Deserialize(ms);
Console.WriteLine(x.GetType());
fs.Close();


}
}
[Serializable]
class A
{
string x = "122";
}
}

大芝麻的主页 大芝麻 | 初学一级 | 园豆:4
提问于:2013-08-16 10:23
< >
分享
最佳答案
0

最简单的方式,把三个对象组合成一个大对象:

public class Big {public A a;public B b;public C c;}

收获园豆:10
Launcher | 高人七级 |园豆:45030 | 2013-08-16 10:27

这个我知道,可是要储存的数据会越来越多,总是用大对象的话,当数据量大到一定程度的时候,岂不是要把整个文件都读到内存中来然后取出自己需要的数据,那样完全不适应呀

大芝麻 | 园豆:4 (初学一级) | 2013-08-16 10:29

@大芝麻: 你以此序列化和读取没什么问题,遇到流结尾,只能说明你序列化时没有把数据从内存刷新到磁盘文件。

Launcher | 园豆:45030 (高人七级) | 2013-08-16 10:44

@Launcher: 你看看这样行不:

FileStream fs = new FileStream("DataFile.dat", FileMode.Open);

BinaryFormatter formatter = new BinaryFormatter();

formatter.Serialize(fs, a);

formatter.Serialize(fs, b);

formatter.Serialize(fs, c);

fs.Flush();

fs.Close();

 

// 读取:

FileStream fs = new FileStream("DataFile.dat", FileMode.Open);

BinaryFormatter formatter = new BinaryFormatter();

A a = (A)formatter.Deserialize(fs);

B b = (B)formatter.Deserialize(fs);

C c = (C)formatter.Deserialize(fs);

fs.Close();

Launcher | 园豆:45030 (高人七级) | 2013-08-16 13:11

@Launcher: 是流指针的问题导致的,我真是菜了,不过学到了些东西

大芝麻 | 园豆:4 (初学一级) | 2013-08-18 17:54
其他回答(3)
0

这快设计到东西很多,很难几行或者几十行搞定。可以去用下NDatabase,或者看下那个的代码。主要就是解决这个问题的。

收获园豆:5
````` | 园豆:14268 (专家六级) | 2013-08-16 10:56

这么复杂啊。。。。我觉得就是序列化成二进制然后存入文件,然后依次按长度取出

支持(0) 反对(0) 大芝麻 | 园豆:4 (初学一级) | 2013-08-16 11:57

@大芝麻: 如果只是简单的存储  然后拿出来,并且就是几个几十个对象直接序列化反序列化,直接用json存储吧。

支持(0) 反对(0) ````` | 园豆:14268 (专家六级) | 2013-08-16 12:03

@imfunny:Json存储确实可行不过,存储的数据有能够直观的看出来内部信息。谢了

支持(0) 反对(0) 大芝麻 | 园豆:4 (初学一级) | 2013-08-18 17:55
0

在序列化时,三个对象之间是如何分隔的?

收获园豆:10
dudu | 园豆:40744 (高人七级) | 2013-08-16 10:57

没分割,按长度取出。第一个对象序列化后长度是120,第二个是27,存入文件

然后用二进制流取出120个byte然后反序列化,移动文件指针到120处,取出便宜27个byte再反序列化

支持(0) 反对(0) 大芝麻 | 园豆:4 (初学一级) | 2013-08-16 11:35

@大芝麻: 那问题可能出在读取流的操作时,在反序列化第2个对象时,流的读取指针已经跑到了流的结尾

支持(0) 反对(0) dudu | 园豆:40744 (高人七级) | 2013-08-16 11:40

@dudu: 如你所说就是指针位置不正确导致的

支持(0) 反对(0) 大芝麻 | 园豆:4 (初学一级) | 2013-08-18 17:54
0

做一个结构体,然后把结构体按序追加到文件中,C++存储数据的模式都这样,可以去看看大智慧的数据存储方式。

收获园豆:5
kylin.chen | 园豆:983 (小虾三级) | 2013-08-16 12:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册