c#异常进程无法访问文件
Posted
技术标签:
【中文标题】c#异常进程无法访问文件【英文标题】:c# Exception The process cannot access the file 【发布时间】:2013-03-26 12:29:42 【问题描述】:我遇到了一个异常:进程无法访问该文件。
代码如下:
if (!Monitor.TryEnter(lockObject))
return;
try
watcher.EnableRaisingEvents = false;
try
XmlDocument xdoc = new XmlDocument();
xdoc.Load(FileName);
xdoc = null;
catch (XmlException xe)
using (StreamWriter w = File.AppendText(FileName))
Console.WriteLine(xe);
w.WriteLine("</test>");
w.WriteLine("</testwrapper>");
System.Threading.Thread.Sleep(2000);
XPathDocument myXPathDoc = new XPathDocument(new StreamReader(FileName, System.Text.Encoding.GetEncoding("windows-1256")));
XslCompiledTransform myXslTrans = new XslCompiledTransform();
myXslTrans.Load("D:/GS/xsl/test.xsl");
XmlTextWriter myWriter = new XmlTextWriter(destinationFile, null);
myWriter.Formatting = Formatting.Indented;
myWriter.Indentation = 4;
myXslTrans.Transform(myXPathDoc, null, myWriter);
myWriter.Close();
catch (Exception e)
Console.WriteLine("The process failed: 0", e.ToString());
finally
Monitor.Exit(lockObject);
watcher.EnableRaisingEvents = true;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
在我添加这些行之前,代码运行良好。这些主要用于测试 xml 文件是否没有结束标签(我通常会添加这些标签)。添加以下代码后,它开始给我这个异常。
try
XmlDocument xdoc = new XmlDocument();
xdoc.Load(FileName);
xdoc = null;
catch (XmlException xe)
using (StreamWriter w = File.AppendText(FileName))
Console.WriteLine(xe);
w.WriteLine("</test>");
w.WriteLine("</testwrapper>");
这里有什么问题?
编辑:我遇到的错误
进程失败:System.IO.IOException:进程无法访问文件'z :\TF_B1BBA.xml' 因为它正被另一个进程使用。 在 System.IO.__Error.WinIOError(Int32 错误代码,字符串可能全路径) 在 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolea n 使用长路径) 在 System.IO.FileStream..ctor(字符串路径,FileMode 模式,FileAccess 访问, FileShare 共享,Int32 bufferSize) 在 System.Xml.XmlDownloadManager.GetStream(Uri uri,ICredentials 凭据, IWebProxy 代理,RequestCachePolicy 缓存策略) 在 System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri,字符串角色,O 类型 对象返回) 在 System.Xml.XmlTextReaderImpl.OpenUrlDelegate(对象 xmlResolver) 在 System.Threading.CompressedStack.runTryCode(对象 userData) 在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCl eanup(TryCode 代码、CleanupCode backoutCode、对象 userData) 在 System.Threading.CompressedStack.Run(CompressedStack 压缩堆栈,续 extCallback 回调,对象状态) 在 System.Xml.XmlTextReaderImpl.OpenUrl() 在 System.Xml.XmlTextReaderImpl.Read() .在 System.Xml.XmlLoader.Load(XmlDocument 文档,XmlReader 阅读器,布尔预置 ve空白) 在 System.Xml.XmlDocument.Load(XmlReader 阅读器) 在 System.Xml.XmlDocument.Load(字符串文件名) 在 C:\ 中的 GSelInterface.Program.convert(Object source, FileSystemEventArgs f) 文档和设置\Administrator\Desktop\ConsoleApplication1\ConsoleApplic ion1\Program.cs:第 178 行
【问题讨论】:
lockobject 和/或 watcher 对象是否以某种方式在同一个文件上工作?它们可能是文件锁定的原因 是的,我有监视对象监视该文件夹。在它拾取它之后,我将它的观察者设置为 false,然后通过它来验证 xml 是否完美(如第二个代码中所示),然后应用 xml 转换。但是在我做这一切之前我确实把观察者设置为假,所以它干扰文件处理的可能性很小甚至没有。也许我错了。帮助我理解。 我尝试删除我在此处使用的线程的锁定对象,但错误仍然相同。 您添加的简单代码将起作用。我按原样尝试了它,即使我认为在 catch 块内做某事不是最佳实践,而且我没有收到文件错误。所以这是锁定文件以进行写入的其他东西,可能在您发布的剪辑之外 完整代码如下:pastebin.com/rFqZVB0H 【参考方案1】:在您的 try 块中,您已经打开了文件。你需要关闭它。
XmlDocument xdoc = new XmlDocument();
xdoc.Load(FileName);
按照这个例子。
http://msdn.microsoft.com/en-us/library/zcsyk915.aspx
【讨论】:
我已经设置为空,不应该这样工作。如果不是最好的卸载方法是什么 你可以调用垃圾收集器来收集内存。 @user726720 这有帮助吗? How to dispose or close an instance of XML Document in ASP.NET 是的,我删除了 xdoc=null。并放入 GC.collect()。还是一样的错误 把 xdoc=cull 和 GC.collect() 两行都去掉,然后试试。【参考方案2】:可能是因为观察者(那么 FileShare.ReadWrite 是重要的部分)。
试试:
XmlDocument xdoc = new XmlDocument();
FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
xdoc.Load(fs);
【讨论】:
当然,我可以试试这个,但我手头有解决方案,请看我的回答。感谢小伙伴的支持。 任何对你有用的东西 :) 只是我曾经遇到过类似的问题(FileSystemWatcher + 在受监视的文件夹中打开文件 + 随机“进程无法访问文件”异常)它对我有用。我检查了你的答案,我想也可以这样做。【参考方案3】:您正在尝试写入已在 try 块中打开的“文件名”文件。
编辑 1:
似乎锁定是由保存文件的进程设置的。 当 convert() 被触发时,文件系统还没有完成保存文件。 如果你有一个大的 xml,它会特别发生。 如果您在尝试写入文件之前添加睡眠,则不会引发异常。
这是一个快速而肮脏的补丁。
如果 xml 文件的保存频率很高,则需要对更改的 xml 文件添加某种锁定。
编辑 2:
尝试在执行操作之前删除观察者的事件,并在一切完成后再次添加,这样可以防止触发多个事件。 不太确定 EnableRaisingEvents = false 是否会以正确的方式工作。 另见这篇文章:
EnableRaisingEvents (enabling and disabling it)
try
watcher.EnableRaisingEvents = false;
//Edit2: Remove the watcher event
watcher.Changed -= new FileSystemEventHandler(convert);
try
XmlDocument xdoc = new XmlDocument();
xdoc.Load(FileName);
catch (XmlException xe)
System.Threading.Thread.Sleep(1000); //added this line
using (StreamWriter w = File.AppendText(FileName))
Console.WriteLine(xe);
w.WriteLine("</test>");
w.WriteLine("</testwrapper>");
/*
Here all xslt transform code
*/
//Edit2: Add again the watcher event
watcher.Changed += new FileSystemEventHandler(convert);
catch (Exception e)
Console.WriteLine("The process failed: 0", e.ToString());
【讨论】:
-1 打开文件的方式或原因。应该怎么做才能修复它?没有回答这个问题。 几乎在同一时间发布了另一个答案,并且一个线程正在进行中。我没有花时间详细说明我的答案,所以也许我不会得到任何 +1,但答案是正确的:“文件中有锁”。问题不是“文件如何或为什么打开” @Draykos:谢谢哥们,只是祈祷你能得到更多的 +1。但是我们还没有对这个问题得出结论。是的,我们现在文件已被锁定,但可以做些什么来解决这个问题。我尝试了各种各样的事情,但无济于事。如果你遇到什么事情,请告诉我。谢谢 是的,做到了。但我仍然遇到同样的异常:进程无法访问文件。这段代码是 convert() 的一部分。如果 convert 被触发,它将首先执行此代码,然后继续应用 xsl。它第一次找到一个文件时并没有给我那个例外。它成功地处理它。第二次找到文件时,它给了我一个错误的直接含义。这意味着它会立即处理它找到的所有文件的捕获(过程失败)。不知道为什么? 尝试在你做事的时候移除事件处理器。请参阅编辑后的答案。【参考方案4】:这个问题的解决方法就在这个链接里:
Exception during xml processing
这是我提出的另一个问题。感谢所有花时间帮助我的人。
【讨论】:
【参考方案5】:确保文件不存在。
我不得不重新创建我的构建配置,而旧文件仍然存在。一旦我删除了旧的转换,我就能够重新创建新的转换。
【讨论】:
以上是关于c#异常进程无法访问文件的主要内容,如果未能解决你的问题,请参考以下文章
c# 读写文件时文件正由另一进程使用,因此该进程无法访问该文件
C# 中的 FileStream 和 FileSystemWatcher,奇怪的问题“进程无法访问文件”