Исключение файла C #: невозможно получить доступ к файлу, потому что он используется другим процессом - PullRequest
7 голосов
/ 24 апреля 2010

Я пытаюсь загрузить файл из Интернета и сохранить его локально, но получаю исключение:

C # Процесс не может получить доступ к файлу «бла», потому что он используется другой процесс.

Это мой код:

File.Create("data.csv");  // create the file
request = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
request.Timeout = 30000;
response = (HttpWebResponse)request.GetResponse();

using (Stream file = File.OpenWrite("data.csv"), // <-- Exception here
    input = response.GetResponseStream())
{
    // Save the file using Jon Skeet's CopyStream method
    CopyStream(input, file);
}

Я видел множество других вопросов за тем же исключением, но ни один из них, похоже, не подходит здесь. Любая помощь?

Обновление:
Спасибо за ответы! Удаление File.Create(...) исправлено!

Один комментарий к документации OpenWrite: это немного вводит в заблуждение, краткое описание гласит:

Открывает существующий файл для записи.

В подробном описании говорится:

Если файл существует , он открывается для писать в начале. Существующий файл не урезан.

Обновление 2.0:
Похоже, что существует несоответствие между IntelliSense / F1 и онлайн-документацией. Я думал, что это должно быть то же самое, так как я позволяю F1 подключаться к сети, когда он отображает документацию.

Ответы [ 4 ]

17 голосов
/ 24 апреля 2010

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

Просто избавьтесь от звонка на File.Create - File.OpenWrite все равно создаст его. В качестве альтернативы, оставьте FileStream рядом, чтобы написать:

using (Stream file = File.Create("data.csv"))
{
    request = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
    request.Timeout = 30000;
    using (var response = (HttpWebResponse)request.GetResponse())
    using (Stream input = response.GetResponseStream())
    {
        // Save the file using Jon Skeet's CopyStream method
        CopyStream(input, file);
    }
}

Обратите внимание, что я также избавляюсь от WebResponse, который вы должны сделать, чтобы убедиться, что соединение освобождено из пула соединений.

6 голосов
/ 24 апреля 2010

похоже на File.Create возвращает открытый объект FileStream

http://msdn.microsoft.com/en-us/library/aa328775(v=VS.71).aspx

попробовать

using (FileStream fs = File.Create("data.csv"))

и пропустите первый File.Create

4 голосов
/ 24 апреля 2010

Проблема в том, что метод File.Create фактически открывает файл и возвращает объект FileStream. Он не закроет файл, пока объект не будет собран мусором (что произойдет в неопределенное время). Объект FileStream по-прежнему создается независимо от того, используете ли вы его или нет. Попробуйте это:

using (Stream file = File.Create("data.csv"),
    input = response.GetResponseStream()) 
{ 
    // Save the file using Jon Skeet's CopyStream method 
    CopyStream(input, file); 
} 
3 голосов
/ 24 апреля 2010

Во-первых. File.Create вернет поток, который вы должны использовать для доступа к файлу.

Во-вторых, если это не решит проблему, если вы Google who lock, вы найдете программу, которая позволит вам определить, какой процесс одновременно обращается к файлу.

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