«Процесс не может получить доступ к файлу X, потому что он используется другим процессом» - C # - PullRequest
2 голосов
/ 06 мая 2011

Я получаю «Процесс не может файл X, потому что он используется другим процессом», когда я выполняю следующий фрагмент кода в моем консольном приложении:

List<string> lines1 = new List<string>();
List<string> lines2 = new List<string>();

string path1 = ConfigurationManager.AppSettings.Get("path1");
string path2 = ConfigurationManager.AppSettings.Get("path2");

File.Create(path1);
File.Create(path2);

foreach (object myObject in myObjects)
{
   //do some fancy logic here!!!
}

File.WriteAllLines(path1, lines1.ToArray());  //exception is thrown here
File.WriteAllLines(path2, lines2.ToArray());

Как я могу решить эту проблему?

Ответы [ 5 ]

5 голосов
/ 06 мая 2011

Вероятная проблема здесь - метод File.Create.Он создает и возвращает дескриптор рассматриваемого файла, завернутый в объект FileStream.Этот объект удерживает файл открытым для записи и, следовательно, блокирует ваш последующий вызов File.WriteAllLines.

Самое простое решение - удалить вызовы File.Create.Просто позвольте методу WriteAllLines создать файл для вас

1 голос
/ 06 мая 2011

У вас есть два варианта: File.Create не только создает файл, но и открывает его. поэтому вам нужно сохранить ссылку на файловый поток и закрыть ее следующим образом:

         var file1 = File.Create(path1);
         var file2 = File.Create(path2);
         file1.Close();
         file2.Close();

ИЛИ вы можете просто пропустить это, потому что File.WriteAllLines(...) создаст файл, если он еще не существует.

Возможно, вы хотите использовать что-то вроде File.Exist для предотвращения других исключений, но это не является частью настоящего вопроса.

0 голосов
/ 06 мая 2011

Если вы удалите строки File.Create, все будет в порядке. Если вы не делаете что-то с файлами в цикле foreach, вам вообще не нужно вызывать методы File.Create. File.WriteAllLines создаст файл, если он не существует. Поскольку метод File.WriteAllLines также закрывает файловый поток, вам не нужно беспокоиться об управлении файловым потоком, возвращаемым File.Create.

0 голосов
/ 06 мая 2011

Согласно моему комментарию выше, File.Create(..) возвращает объект FileStream, который не будет уничтожен, пока метод не будет закрыт (что означает, что дескриптор все еще открыт, таким образом, файл все еще заблокирован).Когда вы пытаетесь использовать WriteAllLines, он пытается открыть новый дескриптор и терпит неудачу, потому что он уже открыт.

Вы можете использовать код, подобный следующему, который отлично работает (только что протестировано):

List<string> lines1 = new List<string>();
string path1 = @"C:\Development\test1.txt";
for (int i = 0; i < 20; i++)
    lines1.Add("Test " + i);

TextWriter textWriter = new StreamWriter(File.Create(path1));
foreach(string line in lines1)
    textWriter.WriteLine(line);
textWriter.Close();

Приведенный выше код будет использовать тот же поток, который был создан при создании файла, поэтому у вас нет шансов на столкновение.

В качестве альтернативы, как и в других ответах, метод File.WriteAllLines создастфайл для вас в любом случае!

0 голосов
/ 06 мая 2011

File.Create (path1) открывает и сохраняет файл открытым и, следовательно, блокирует его.

File.WriteAllLines создаст файл, поэтому нет необходимости сначала его создавать.

Если вам нужно сначала создать его (например, для проверки пути), вы можете сделать

    FileStream fs = File.Create(path1);
    fs.Close();
...