gpt4 book ai didi

C# 从文件序列化数据契约(Contract)

转载 作者:行者123 更新时间:2023-11-30 12:34:09 25 4
gpt4 key购买 nike

我有一个 Xml 消息列表,特别是我记录到文件中的 DataContract 消息。我正试图从文件中一个一个地反序列化它们。我不想一次将整个文件读入内存,因为我预计它会非常大。

我有一个这个序列化的实现并且有效。我通过使用 FileStream 进行序列化并读取字节并使用正则表达式来确定元素的结尾来做到这一点。然后获取元素并使用 DataContractSerializer 获取实际对象。

但我被告知我应该使用更高级别的代码来完成这项任务,而且看起来这应该是可能的。我有以下代码,我认为它应该可以工作,但它没有。

FileStream readStream = File.OpenRead(filename);
DataContractSerializer ds = new DataContractSerializer(typeof(MessageType));
MessageType msg;
while ((msg = (MessageType)ds.ReadObject(readStream)) != null)
{
Console.WriteLine("Test " + msg.Property1);
}

上面的代码由一个包含以下内容的输入文件提供:

<MessageType>....</MessageType>
<MessageType>....</MessageType>
<MessageType>....</MessageType>

看来我可以正确读取和反序列化第一个元素,但之后它失败了:

System.Runtime.Serialization.SerializationException was unhandled
Message=There was an error deserializing the object of type MessageType. The data at the root level is invalid. Line 1, position 1.
Source=System.Runtime.Serialization

我在某处读到这是由于 DataContractSerializer 与填充的 '\0' 一起工作到最后的方式 - 但我无法弄清楚从流中读取时如何解决这个问题而没有弄清楚结尾MessageType 标记以其他方式。我应该使用另一个序列化类吗?还是解决这个问题的方法?

谢谢!

最佳答案

当您反序列化文件中的数据时,WCF 默认使用只能使用适当的 XML 文档的读取器。您正在阅读的文档不是 - 它包含多个根元素,因此它实际上是一个片段。您可以通过使用 ReadObject 的另一个重载来更改序列化程序正在使用的阅读器,如下例所示,到一个接受片段的(通过使用 XmlReaderSettings 对象)。或者您可以在 <MessageType> 周围使用某种包装元素元素,您会一直阅读,直到读者定位到包装器的末尾元素。

public class StackOverflow_7760551
{
[DataContract]
public class Person
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }

public override string ToString()
{
return string.Format("Person[Name={0},Age={1}]", this.Name, this.Age);
}
}

public static void Test()
{
const string fileName = "test.xml";
using (FileStream fs = File.Create(fileName))
{
Person[] people = new Person[]
{
new Person { Name = "John", Age = 33 },
new Person { Name = "Jane", Age = 28 },
new Person { Name = "Jack", Age = 23 }
};

foreach (Person p in people)
{
XmlWriterSettings ws = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
OmitXmlDeclaration = true,
Encoding = new UTF8Encoding(false),
CloseOutput = false,
};
using (XmlWriter w = XmlWriter.Create(fs, ws))
{
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
dcs.WriteObject(w, p);
}
}
}

Console.WriteLine(File.ReadAllText(fileName));

using (FileStream fs = File.OpenRead(fileName))
{
XmlReaderSettings rs = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
};
XmlReader r = XmlReader.Create(fs, rs);
while (!r.EOF)
{
Person p = new DataContractSerializer(typeof(Person)).ReadObject(r) as Person;
Console.WriteLine(p);
}
}

File.Delete(fileName);
}
}

关于C# 从文件序列化数据契约(Contract),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7760551/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com