4

我遇到了一个例外:该进程无法访问该文件。

这是代码:

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 errorCode, String maybeFullPath) 在 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions 选项, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize) at System.Xml.XmlDownloadManager.GetStream(Uri uri, System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofO bjectToReturn) 在 System.Xml 中的 ICredentials 凭据、IWebProxy 代理、RequestCachePolicy cachePolicy)。XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver) 在 System.Threading.CompressedStack.runTryCode(Object userData) 在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCl eanup(TryCode 代码, CleanupCode backoutCode, Object userData) 在 System.Threading.CompressedStack.Run(CompressedStack在 System.Xml.XmlTextReaderImpl.OpenUrl() 在 System.Xml.XmlTextReaderImpl.Read() 的压缩堆栈,Cont extCallback 回调,对象状态。在 System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean prese veWhitespace) at System.Xml.XmlDocument.Load(XmlReader reader) at System.Xml.XmlDocument.Load(String filename) at GSelInterface.Program.convert( C 中的对象源 FileSystemEventArgs f):

4

5 回答 5

4

在您的尝试块中,您已经打开了文件。你需要关闭它。

XmlDocument xdoc = new XmlDocument();
xdoc.Load(FileName);

按照这个例子。

http://msdn.microsoft.com/en-us/library/zcsyk915.aspx

于 2013-04-04T12:32:21.720 回答
4

这可能是因为观察者(然后 FileShare.ReadWrite 是重要的部分)。

尝试:

XmlDocument xdoc = new XmlDocument();
FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
xdoc.Load(fs);
于 2013-04-05T12:31:35.120 回答
0

您正在尝试写入已在 try 块中打开的“文件名”文件。

编辑1:

似乎锁定是由保存文件的进程设置的。当 convert() 被触发时,文件系统还没有完成保存文件。如果你有一个大的 xml,它会特别发生。如果您在尝试写入文件之前添加睡眠,则不会引发异常。

这是一个快速而肮脏的补丁。

如果 xml 文件的保存频率很高,则需要对更改的 xml 文件添加某种锁定。

编辑2:

还可以尝试在执行操作之前删除观察者的事件,并在一切完成后再次添加,这样可以防止多个事件被触发。不太确定 EnableRaisingEvents = false 是否会以正确的方式工作。另见这篇文章:

EnableRaisingEvents(启用和禁用它)

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());
}
于 2013-04-04T12:30:09.310 回答
0

这个问题的解决方案就在这个链接上:

xml处理期间的异常

这是我提出的另一个问题。感谢所有花时间帮助我的人。

于 2013-04-05T13:24:36.420 回答
0

确保该文件不存在。

我不得不重新创建我的构建配置并且旧文件仍然存在。一旦我删除了旧的转换,我就能够重新创建新的转换。

于 2016-07-19T16:37:49.327 回答