我正在开发一个程序来记录来自传入串行通信的数据。我必须通过发送命令来调用串行盒来接收一些东西。这一切都很好,但我有一个问题。
该程序必须从上网本(约1.5 gHZ,2 gig ram)运行,当我要求它将这些信息保存到XML文件时,它无法跟上。
我每隔5秒才收到一次通讯,我不是在任何地方读文件。
我使用xml.save(字符串文件名)来保存文件。
还有另一种更好的方法是将信息保存到我的XML中,还是应该使用替代方法?
如果我应该使用替代品,它应该是什么?
编辑: 添加了一些代码:
XmlDocument xml = new XmlDocument();
xml.Load(logFile);
XmlNode p = xml.GetElementsByTagName("records")[0];
for (int i = 0; i < newDat.Length; i++)
{
XmlNode q = xml.CreateElement("record");
XmlNode a = xml.CreateElement("time");
XmlNode b = xml.CreateElement("temp");
XmlNode c = xml.CreateElement("addr");
a.AppendChild(xml.CreateTextNode(outDat[i, 0]));
b.AppendChild(xml.CreateTextNode(outDat[i, 1]));
c.AppendChild(xml.CreateTextNode(outDat[i, 2]));
sendTime = outDat[i, 0];
points.Add(outDat[i, 2], outDat[i, 1]);
q.AppendChild(a);
q.AppendChild(b);
q.AppendChild(c);
p.AppendChild(q);
}
xml.AppendChild(p);
xml.Save(this.logFile);
这是与XML相关的代码,每5秒运行一次。我正在阅读(我没有错误),添加一些孩子,然后再次保存。当我保存时,我得到了错误。
答案 0 :(得分:6)
您可能希望查看使用XMLWriter并手动构建XML文件 。这将允许您打开文件并在日志记录期间保持打开状态,在读取数据时一次附加一个XML片段。 XMLReader类针对仅向前写入XMLStream进行了优化。
与使用Save方法在每次读取数据时序列化(保存)完整的XML文档以及最后只想在末尾添加新片段相比,上述方法应该快得多。
修改强>
根据您发布的代码示例,加载和保存会导致不必要的性能瓶颈。每次添加日志条目时,您实际上都会加载完整的XML文档,并在后台将其解析为完整的XML树。然后修改树(通过添加节点),然后再将其全部序列化为磁盘。这非常适得其反。
我建议的解决方案真的是要走的路:只创建和打开一次日志文件;然后每次读取新数据时,使用XMLWriter逐个写出XML元素;这样你就不会在内存中保存XML日志的全部内容,而只是在文件末尾附加小块数据 - 这在开销方面应该是不可察觉的;最后,只需关闭根XML标记,关闭XMLWriter并关闭文件。而已!即使您在UI线程上同步实现它,也可以保证不会降低UI的速度。
答案 1 :(得分:1)
虽然不能直接回答你的问题,但听起来你是以非常线性的方式做所有事情:
我建议你考虑使用一些线程,或者可能Task
来使这更加异步。这肯定会更加困难,你必须与任务同步搏斗,但从长远来看,它会表现得更好。
我会看到一个线程(可能是主线程,不确定你是否使用WinForms,一个控制台应用程序或什么)接收命令,并将“更改”发布到一个保持类。然后有第二个线程,它定期轮询这个保持类并检查它是否为“脏”状态。当它检测到此状态时,它会抓取XML的副本并将其保存到磁盘。
这使您的串行通信能够不间断地继续运行,无论您运行的硬件的性能有多差。
答案 2 :(得分:1)
通常对于日志文件,一个选择附加友好格式,否则每次需要追加新记录并保存结果时都必须重新解析整个文件。纯文本CSV可能是最简单的选项。
如果您需要具有类似XML的文件,则另一个选项是存储XML片段列表而不是完整XML。这样你仍然可以使用XML API(XmlReader可以在XmlReader.Create调用的XmlReaderSettings中指定ConformanceLevel.Frament
时读取片段),但是你不需要重新读取整个文档来附加新条目 - 简单文件级追加就够了。即WCF日志以这种方式编写。
答案 3 :(得分:0)
如果您的输出必须是XML格式的文件,那么@Miky Dinescu的答案就是这样做的一种方法。原因是您每次添加另一个条目时都要求它完成加载并重新分析整个XML文件。加载和解析XML文件会使文件越大,IO,内存和CPU密集程度越来越大。因此,如果必须在非常有限的时间范围内运行,任何硬件的开销都不会很长。否则,您需要重新考虑整个过程,并且可以简单地将所有数据缓冲到内存缓冲区中,您可以以更加悠闲的速度写出(刷新)。
答案 4 :(得分:0)
我做了这项工作,但我不相信这是“最佳实践”方法。
我有另一个班级,我的XmlDocument
一直在运行,然后尝试以保存每次添加数据。如果失败,它只是等待下次保存。
我会建议其他人看看Miky Dinescu的建议。我只是觉得自己很想改变如何保存数据。