这是我的代码,它打开XML文件(old.xml),过滤无效字符并写入另一个XML文件(abc.xml)。最后,我将再次加载XML(abc.xml)。执行跟随行时,有异常说xml文件由另一个进程使用
xDoc.Load("C:\\abc.xml");
有没有人有任何想法有什么不对?我的代码中有任何泄漏以及为什么(我一直在使用“使用”关键字,看到泄漏感到困惑......)
这是我的整个代码,我在Windows Vista x64下使用C#+ VSTS 2008。
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
Encoding encoding = Encoding.GetEncoding("utf-8", new EncoderReplacementFallback(String.Empty), new DecoderReplacementFallback(String.Empty));
using (TextWriter writer = new StreamWriter(new FileStream("C:\\abc.xml", FileMode.Create), Encoding.UTF8))
{
using (StreamReader sr = new StreamReader(
"C:\\old.xml",
encoding
))
{
int bufferSize = 10 * 1024 * 1024; //could be anything
char[] buffer = new char[bufferSize];
// Read from the file until the end of the file is reached.
int actualsize = sr.Read(buffer, 0, bufferSize);
writer.Write(buffer, 0, actualsize);
while (actualsize > 0)
{
actualsize = sr.Read(buffer, 0, bufferSize);
writer.Write(buffer, 0, actualsize);
}
}
}
try
{
XmlDocument xDoc = new XmlDocument();
xDoc.Load("C:\\abc.xml");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
EDIT1:我试图将缓冲区的大小从10M更改为1M,它可以工作!我很困惑,有什么想法吗?
EDIT2:我发现当输入的旧XML文件非常大时,例如100M或其他东西,这个问题很容易重现。我怀疑它是否是.Net已知错误?我将使用ProcessExplorer / ProcessMonitor等工具来查看哪个进程锁定文件以防止XmlDocument.Load访问该文件。
答案 0 :(得分:4)
这对我来说很好。 纯粹猜测,但也许病毒检查员正在扫描文件? 要进行调查,请尝试禁用病毒检查程序并查看其是否有效(然后重新启用病毒检查程序)。
顺便说一下,可以让文件保持打开的一种方式:如果StreamReader
构造函数抛出异常;但是,无论如何你都不会达到XmlDocument
的东西......但请考虑:
using (FileStream fs = new FileStream("C:\\abc.xml", FileMode.Create))
using (TextWriter writer = new StreamWriter(fs, Encoding.UTF8))
{
...
}
现在fs
处于new StreamWriter(...)
抛出的边缘情况中。但是,我不认为这是问题所在。
答案 1 :(得分:2)
您可能在根目录上运行FileSystemWatcher?
您还可以使用ProcessMonitor查看访问该文件的人员。
答案 2 :(得分:2)
问题是你的char[]
似乎很大。如果它太大,它位于大型objekt堆上,而不是堆栈上。因此,只要软件正在运行,大型对象堆就不会被压缩,一旦分配的空间可能不会再次使用 - 这看起来像是内存泄漏。尝试将阵列拆分为较小的块。
答案 3 :(得分:2)
我的第二个Leppie建议使用ProcessMonitor(或等效的)来确定谁锁定文件。其他任何事情都只是猜测。
答案 4 :(得分:1)
您的缓冲区未被释放,是吗?
答案 5 :(得分:1)
代码工作正常。刚检查过。
答案 6 :(得分:1)
使用会调用Dispose
,但Dispose
会在写入流上调用close吗?如果没有,系统仍可以认为该文件是开放的。
我会尝试在其writer
块结束之前结束using
。
编辑:我自己也试过了代码。编译并运行没有你看到的问题。尝试像其他人提到的那样关闭病毒扫描程序,并确保在文件打开的地方没有窗口。
答案 7 :(得分:1)
您是否检查过没有其他进程尝试访问该文件?
答案 8 :(得分:1)
它适用于某些人而不适用于其他人的事实使我认为该文件未被关闭。在尝试加载文件之前关闭编写器。
答案 9 :(得分:1)
我敢打赌,你有一些防病毒解决方案正在运行,它会在文件关闭后锁定。要进行验证,请尝试在加载文件之前添加延迟(例如,1秒)。如果可行的话,你可能找到了原因。
答案 10 :(得分:0)
确保您的程序首先锁定文件。