Процесс не может получить доступ к файлу С#

426
03 мая 2017, 07:31

я делаю файловый менеджер на c#. У меня возникла проблема(картинка прилагается). Такое возникает когда я создаю файл и потом пытаюсь его переместить или скопировать, уже ранее созданные файлы нормально перемещаются и копируются.

Answer 1

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

Без освобождения потока:

Stream myStream;
using (myStream = File.Open(@"\test.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
    StreamWriter myWriter = new StreamWriter(myStream);
    myWriter.WriteLine("test");
    //перед чтением необходимо вернуть указатель потока в нужное место, у меня - в начало файла.
    myStream.Position = 0;
    StreamReader myReader = new StreamReader(myStream);
    Console.Write(myReader.ReadToEnd());
}

При таком подходе важно указать FileAccess.ReadWrite при создании потока и не закрывать StreamWriter и StreamReader, т.к. они при закрытии закрывают и поток. На все время работы файл будет заблокирован для других приложений.

С освобождением потока:

Stream myStream;
using (myStream = File.Open(@"\test.txt",FileMode.OpenOrCreate,FileAccess.Write))
{
    StreamWriter myWriter = new StreamWriter(myStream);
    myWriter.WriteLine("test");
}
using (myStream = File.Open(@"\test.txt", FileMode.OpenOrCreate, FileAccess.Read))
{
    StreamReader myReader = new StreamReader(myStream);
    Console.Write(myReader.ReadToEnd());
}

В этом случае после чтения и записи поток освобождается. Соответственно между чтением и записью (в любом порядке) файл доступен другим процессам.

Блоки using гарантируют освобождение потока. Вместо этого можно использовать myStream.Close(), но про это можно случайно забыть, так что using надежнее.

В принципе, отдельно поток можно и не создавать, StreamWriter и StreamReader сами умеют создавать поток к файлу по его имени, в таком случае код короче:

using (StreamWriter myWriter = new StreamWriter(@"\test.txt"))
{
    myWriter.WriteLine("test");
}
using (StreamReader myReader = new StreamReader(@"\test.txt"))
{
    Console.Write(myReader.ReadToEnd());
}

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

Кроме всего перечисленного крайне желательно прежде чем открывать потоки чтения-записи, проверять существование файла, наличие необходимых прав доступа и т.д. потому что отсутствие какой либо из проверок в большинстве случаев гарантирует исключение.

Answer 2

"я создаю файл и потом пытаюсь его переместить" - не закрыли созданный файл:

https://msdn.microsoft.com/en-us/library/system.io.fileinfo.create(v=vs.110).aspx

using (FileStream fs = newFile.Create()) 
{
}
READ ALSO
OxyPlot LinearAxis конвертировать значение в DateTime

OxyPlot LinearAxis конвертировать значение в DateTime

Строится график значение по х от 0 до 1000Как конвертировать эти значение в DateTime? Нужно чтоб подписи на шкале были не (0, 100, 200

376
Как удалить пробелы из объекта?

Как удалить пробелы из объекта?

Необходимо удалить пробелы из объекта, через Trim() и Replace() - не получаетсяПишет, что ссылка на объект не указывает на экземпляр объекта

333
Как можно получить список ПК в домене?

Как можно получить список ПК в домене?

Как можно получить список ПК в домене(ip, имена ПК), находясь вне домена и имея доменную учётку?

227
Достигнуто максимальное значение пула

Достигнуто максимальное значение пула

Подскажите пожалуйста, как решить вопрос с соединениемИспользую базу данных MySQL, в программе к ней куча различных запросов

284