Блокировка файлов при использовании file.move в c # ... как я могу остановить или исправить это - PullRequest
3 голосов
/ 26 февраля 2010

Код:

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

блокирует файл, и я больше не могу писать в него.

Ответы [ 2 ]

3 голосов
/ 26 февраля 2010

Вы должны закрыть свои StreamReader и StreamWriter в using заявлениях, например:

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");
0 голосов
/ 10 мая 2019

У меня была похожая ситуация с файлами результатов XML, созданными программой запуска консоли xUnit. Я добавляю его в качестве ответа здесь на тот случай, если это поможет другим найти причину / решение, когда 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;
        }
    }
}

Конечно, задним числом очевидно, что мне не удалось закрыть XmlTextReader, который включает базовый StreamReader, и что это оставляло блокировки для файлов результатов 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 с использованием консоли запуска тестов xUnit и сообщает программе запуска консоли xUnit создание файлов результатов XML с помощью параметра командной строки. SpecFlow также задействован поверх слоя бегуна тестов xUnit, но файлы результатов xUnit - это то, что читается. После выполнения теста я хотел переместить файлы результатов XML в архивные папки на основе даты, и эта операция File.Move () не выполнялась из-за блокировок в файлах результатов xUnit, как результат кода без блока using.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...