在c#中使用File.move时文件锁定…如何停止或修复此问题

在c#中使用File.move时文件锁定…如何停止或修复此问题,c#,file,filelock,C#,File,Filelock,代码: 如果挂起的.txt文件不存在,则在程序启动时创建该文件。此代码删除文件的第一行。当我调试代码时,我注意到 String tempFile = Path.GetTempFileName(), read = ""; TextReader pending = new StreamReader("c:\\pending.txt"); TextWriter temp = new StreamWriter(tempFile); rea

代码:

如果挂起的.txt文件不存在,则在程序启动时创建该文件。此代码删除文件的第一行。当我调试代码时,我注意到

        String tempFile = Path.GetTempFileName(), read = "";
        TextReader pending = new StreamReader("c:\\pending.txt");
        TextWriter temp = new StreamWriter(tempFile);

        read = pending.ReadLine();

        while ((read = pending.ReadLine()) != null)
        {
            temp.WriteLine(read);
        }

        pending.Close();
        temp.Close();

        File.Delete("c:\\pending.txt");
        File.Move(tempFile, "c:\\pending.txt");

锁定文件,我无法再写入该文件。

您应该使用语句关闭
中的
StreamReader
StreamWriter
,如下所示:

        File.Move(tempFile, "c:\\pending.txt");
   public void ReadResultsXmlFile(string testResultsXmlFile)
{
    MyXmlTextReader = new XmlTextReader(testResultsXmlFile);
    testResultXmlDocument = new XmlDocument();
    testResultXmlDocument.Load(MyXmlTextReader); 
    XmlNode xnAssembliesHeader = testResultXmlDocument.SelectSingleNode("/assemblies");
    XmlNodeList xnAssemblyList = testResultXmlDocument.SelectNodes("/assemblies/assembly");
    foreach (XmlNode assembly in xnAssemblyList)
    {
        XmlNodeList xnTestList = testResultXmlDocument.SelectNodes(
            "/assemblies/assembly/collection/test");
        foreach (XmlNode test in xnTestList)
        {
            TestName = test.Attributes.GetNamedItem("name").Value;
            TestDuration = test.Attributes.GetNamedItem("time").Value;
            PassOrFail = test.Attributes.GetNamedItem("result").Value;
        }
    }
}

我对xUnit控制台运行程序生成的XML结果文件也有类似的情况。我在这里添加它作为一个答案,以防当StreamReader以XmlTextReader的形式构建在Stream和TextReader之上时,它可以帮助其他人找到原因/解决方案,并且还可以在底层文件上放置锁,如果底层流和读卡器在读取完成时未关闭并立即处理,则后续的移动和删除操作将失败

String tempFile = Path.GetTempFileName(), read = "";
using(TextReader pending = new StreamReader("c:\\pending.txt"))
using(TextWriter temp = new StreamWriter(tempFile))
{

    read = pending.ReadLine();

    while ((read = pending.ReadLine()) != null)
    {
        temp.WriteLine(read);
    }
}

File.Delete(@"c:\pending.txt");
File.Move(tempFile, @"c:\pending.txt");
当然,事后看来很明显,我没有关闭包含底层StreamReader的XmlTextReader,这会在XML结果文件上留下锁

固定代码如下所示:

        File.Move(tempFile, "c:\\pending.txt");
   public void ReadResultsXmlFile(string testResultsXmlFile)
{
    MyXmlTextReader = new XmlTextReader(testResultsXmlFile);
    testResultXmlDocument = new XmlDocument();
    testResultXmlDocument.Load(MyXmlTextReader); 
    XmlNode xnAssembliesHeader = testResultXmlDocument.SelectSingleNode("/assemblies");
    XmlNodeList xnAssemblyList = testResultXmlDocument.SelectNodes("/assemblies/assembly");
    foreach (XmlNode assembly in xnAssemblyList)
    {
        XmlNodeList xnTestList = testResultXmlDocument.SelectNodes(
            "/assemblies/assembly/collection/test");
        foreach (XmlNode test in xnTestList)
        {
            TestName = test.Attributes.GetNamedItem("name").Value;
            TestDuration = test.Attributes.GetNamedItem("time").Value;
            PassOrFail = test.Attributes.GetNamedItem("result").Value;
        }
    }
}

值得一提的是,该应用程序是一个测试运行程序,使用xUnit控制台测试运行程序运行基于Selenium的自动化web测试,并通过命令行选项告诉xUnit控制台运行程序创建XML结果文件。在xUnit测试运行器层的顶部,也涉及SpecFlow,但xUnit结果文件是正在读取的。在测试执行之后,我想将XML结果文件移动到基于日期的归档文件夹中,而File.move()操作由于xUnit结果文件上的锁而失败,这是因为代码没有使用块。

我还建议,如果您自己复制一个文件,请在固定大小的块(4K,8K?)中进行复制比一行一行更有效。我试过了,但结果还是一样的。现在的情况是,顺便说一下,我有Windows7,只要程序点击“File.Move”,我就会在文件的图标上看到一个锁图像。在此之后,我无法将任何内容写入该文件。它看起来像是在写,但当我通过windows资源管理器打开它时,文件没有更改。我说文件正在使用中也没有错误。你的回答帮助了我,投了赞成票,谢谢!!我添加了一个答案,我希望它能帮助那些除了XmlTextReaders之外基本上存在相同问题的人。我没有想起需要关闭的底层StreamReader。这看起来像是一个许可问题。没关系。Windows资源管理器仍然显示一个锁定的图标,但我的其余代码是错误的。很抱歉但是谢谢你的使用提示。我必须更深入地研究readBlock。