我尝试以这种方式序列化15个对象的列表:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Employee>));
MemoryStream memStream = new MemoryStream();
// Serialize
xmlSerializer.Serialize(stream, allKnownWorkers);
memStream.Position = 0;
data = memStream.GetBuffer();
Console.WriteLine("Transmitting.....");
stream.Write(data, 0, data.Length); // NetworkStream
反序列化看起来像:
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Employee>));
MemoryStream memStream = new MemoryStream();
memStream.Write(data, 0, bytes);
memStream.Position = 0;
// Deserialize
workers.AddRange((List<Employee>)xmlSerializer.Deserialize(memStream));
我在反序列化的最后一行得到一个例外:Unexpected end of file has occurred. The following elements are not closed: ...
当我发送只包含少量对象的列表时,它可以正常工作。我想流缓冲区长度有问题。我该如何解决?
非常感谢!
答案 0 :(得分:1)
您将基于流的网络连接视为基于消息。但事实并非如此。因此,您无法依靠流中的单个读取返回单个对象的所有数据,甚至单个传输。
相反,您需要在协议中设计一种方法来了解何时读取了处理单元的所有数据(无论在给定的上下文中发生了什么......这里似乎是一个XML文档)。
有很多方法可以实现这一目标。我想说最直接的两个方法是先在XML数据之前传输字节数,以便接收者知道在尝试读取XML之前要读取多少字节,或者简单地将XML解析构建到流中读数。
在后一点上,您可以尝试将网络流传递给XmlSerializer。我不记得我的头脑是如何处理它的,但只要XmlSerializer在获得完整的XML文档后停止读取它就可以工作,而不是试图一直读到结束时流。但即使XmlSerializer不仅仅是免费提供给你,也不应该太难以检测XML文档的根元素的开始标记,然后只是继续阅读数据,直到你读到结束标记。