【问题标题】:File locks when using file.move in c#...how can I stop or fix this在 c# 中使用 file.move 时文件锁定...如何停止或修复此问题
【发布时间】:2010-02-26 03:51:45
【问题描述】:

代码:

        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");

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

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

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

【问题讨论】:

  • 这看起来像是一个权限问题。
  • 没关系。 Windows 资源管理器仍然显示锁定图标,但我的其余代码是错误的。对不起。但感谢使用提示。我必须更多地研究 readBlock。

标签: c# file filelock


【解决方案1】:

您应该在using 语句中关闭您的StreamReaderStreamWriter,如下所示:

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");

【讨论】:

  • 我还建议,如果您自己复制文件,以固定大小的块(4K、8K?)这样做比逐行更有效。
  • 我试过这个,但它仍然给出相同的结果。发生的事情是,顺便说一句,我有 Windows 7,只要程序点击“File.Move”,我就会在文件图标上看到一个锁定图像。在此之后,我无法向文件写入任何内容。它看起来像它写的,但是当我通过 Windows 资源管理器打开它时文件没有改变。我也没有说文件正在使用中的错误。
  • 你的回答对我有帮助,点赞,谢谢!!我添加了一个答案,希望能帮助那些除了 XmlTextReaders 之外遇到基本相同问题的人。我没有回忆起需要关闭的底层 StreamReader。
【解决方案2】:

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

   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;
        }
    }
}

当然,事后看来,很明显我未能关闭包含底层 StreamReader 的 XmlTextReader,这会在 XML 结果文件上留下锁。

固定代码如下所示:

   public void ReadResultsXmlFile(string testResultsXmlFile)
    {
        using (MyXmlTextReader = new XmlTextReader(testResultsXmlFile))
        {
            testResultXmlDocument = new XmlDocument();
            testResultXmlDocument.Load(MyXmlTextReader); // suppose that myXmlString contains "<Names>...</Names>"
            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;
                }
            }
        }
    }

...随后移动和删除操作的锁定文件问题消失了。关键线当然是

using (MyXmlTextReader = new XmlTextReader(testResultsXmlFile))
{
// Do stuff inside "using...  block
} // At close of "using" block, objects in using get Released...

对于它的价值,该应用程序是一个测试运行器,它运行基于 Selenium 的自动化 Web 测试,使用 xUnit 控制台测试运行器,并通过命令行选项告诉 xUnit 控制台运行器创建 XML 结果文件。在 xUnit 测试运行器层之上还涉及 SpecFlow,但正在读取 xUnit 结果文件。在测试执行之后,我想将 XML 结果文件移动到基​​于日期的存档文件夹中,并且由于 xUnit 结果文件上的锁定,File.Move() 操作失败,这是由于代码没有使用块。

【讨论】:

    猜你喜欢
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-13
    相关资源
    最近更新 更多