gpt4 book ai didi

c# - 在 C# 中动态序列化大量对象而不是一次全部序列化?

转载 作者:太空宇宙 更新时间:2023-11-03 21:54:32 26 4
gpt4 key购买 nike

我创建了几个类来表示关系数据结构(父子结构)。下面是到目前为止的 XML 表示示例,可以让您了解我的意思

<BillingFile>
<Account>
<acctnum>122344231414</acctnum>
<adjustments>34.44</adjustments>
<Charges>
<lineitem>
<chargetype>PENALTY</chargetype>
<amount>40.50</amount>
<ratecode>E101</ratecode>
</lineitem>
<lineitem>
<chargetype>LATE CHARGE</chargetype>
<amount>445.35</amount>
<ratecode>D101</ratecode>
</lineitem>
</Charges>
</Account>
</BillingFile>

我对我的应用程序所做的是解析一个大文本文件,其中可能包含超过 50,000 个帐户。每次读取一个帐户时,我都会创建一个具有父对象等的“帐户”对象。最终目标是能够创建一个 XML 文件,其中包含从创建的对象序列化的所有这些帐户信息。

我看到的问题是,如果我将所有这些对象存储在内存中,它将导致性能问题,因为它在那些 50k+ 记录文件中运行。

我想知道的是,有没有办法在 C# 中顺序序列化一个对象,而不是一次全部序列化?

我进行了一些谷歌搜索,似乎 .NET 的内置序列化方法是一种既定的交易。有没有更好的方法可以做到这一点?

我宁愿避免必须执行任何中间步骤,例如将数据存储在数据库中,因为修改代码比处理一堆表和 JOIN 语句更容易。

想法?

最佳答案

XmlSerializer.Deserialize 需要 XmlReader 范围。你可以把 XmlReader就在 <Account>标记,并调用 XmlSerializer那里。

public IEnumerable<Account> ReadAccounts(TextReader source)
{
var ser = new XmlSerializer(typeof(Account));

using (var reader = XmlReader.Create(source))
{
if (!reader.IsStartElement("BillingFile"))
{
yield break;
}

reader.Read();

while (reader.MoveToContent() == XmlNodeType.Element)
{
yield return (Account) ser.Deserialize(reader);
}
}
}

连载也类似

public void WriteAccounts(IEnumerable<Account> data, TextWriter target)
{
// Use XmlSerializerNamespaces to supress xmlns:xsi and xmlns:xsd
var namespaces = new XmlSerializerNamespaces();
namespaces.Add("", "");

var ser = new XmlSerializer(typeof(Account));

using (var writer = XmlWriter.Create(target))
{
writer.WriteStartElement("BillingFile");

foreach (var acct in data)
{
ser.Serialize(writer, acct, namespaces);
writer.Flush();
}

writer.WriteEndElement();
}
}

您还可以创建一个 BillingFile实现 IXmlSerializable 的类,并将此功能放在那里。

或者如果您更喜欢基于推送的模型:

public class AccountWriter : IDisposable
{
private XmlWriter _writer;
private XmlSerializer _ser;
private XmlSerializerNamespaces _namespaces;

private bool _wroteHeader = false;
private bool _disposed = false;

public bool IsDisposed { get { return _disposed; } }

public AccountWriter(TextWriter target)
{
_namespaces = new XmlSerializerNamespaces();
_namespaces.Add("", "");

_ser = new XmlSerializer(typeof(Account));

_writer = XmlWriter.Create(target);
}

public void Write(Account acct)
{
if (_disposed) throw new ObjectDisposedException("AccountWriter");

if (!_wroteHeader)
{
_writer.WriteStartElement("BillingFile");
_wroteHeader = true;
}

_ser.Serialize(_writer, acct, _namespaces);
}

public void Flush()
{
if (_disposed) throw new ObjectDisposedException("AccountWriter");
_writer.Flush();
}

public void Dispose()
{
if (!_disposed)
{
if (_wroteHeader)
{
_writer.WriteEndElement();
_wroteHeader = true;
}

_writer.Dispose();
_disposed = true;
}
}
}
using (var writer = new AccountWriter(Console.Out))
{
foreach (var acct in accounts)
{
writer.Write(acct);
}
}

关于c# - 在 C# 中动态序列化大量对象而不是一次全部序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12825338/

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