Raspberry Pi上C#应用重复加载XML报根元素缺失异常
XML文件修改后读取报“根元素缺失”异常的原因
我在树莓派上运行一个C#应用,启动时读取一次XML配置文件,之后通过检查文件最后修改时间触发重新读取,读取代码如下:
using System.Xml; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(settingsFileName);
首次启动时读取正常,但文件修改后总会抛出如下异常:
Unhandled exception. System.Xml.XmlException: Root element is missing. at System.Xml.XmlTextReaderImpl.Throw(Exception e) at System.Xml.XmlTextReaderImpl.ParseDocumentContent() at System.Xml.XmlTextReaderImpl.Read() at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace) at System.Xml.XmlDocument.Load(XmlReader reader) at System.Xml.XmlDocument.Load(String filename)
配置文件内容:
<config> <data1 seconds = "5000"></data1> <data2 check = "16:00"></data2> <data3 max = "50"></data3> </config>
补充信息
- 仅修改文件中的数据,未改动根元素
config - 在文件顶部添加
<?xml version="1.0"?>后情况略有改善,但第二次修改文件时仍会报错 - 应用中无修改该文件的代码,仅通过检查文件最后保存时间触发重新读取
- 通过WinSCP默认编辑器(SSH访问树莓派)修改文件
- 使用的.NET版本:
dotnet --version 3.1.425
异常原因分析
核心问题出在WinSCP的远程文件编辑机制与应用读取时机的冲突:
WinSCP默认编辑远程文件时,并非直接修改原文件,而是采用“本地编辑后上传覆盖”的流程:
- 先删除树莓派上的原配置文件
- 将本地编辑好的新文件上传到原路径
当应用检测到文件修改时间变化后立即触发读取,很可能刚好撞上“原文件已删除、新文件还未上传完成”的间隙,此时读取的是一个空文件(或不完整的文件),自然会抛出“根元素缺失”的异常。
另外,即使是直接修改文件的编辑器,也可能存在“先清空原文件内容、再写入新内容”的操作顺序,这个短暂的空文件状态也会被应用的修改时间检测捕捉到,导致读取失败。
添加XML声明后情况略有改善,只是因为首次上传后的文件结构更规范,但无法解决文件替换过程中出现的空文件/不完整文件问题,所以第二次修改仍会报错。
内容的提问来源于stack exchange,提问作者Koenieboy
相关产品推荐
相关产品推荐

