FileStream для сохранения файла, а затем немедленно разблокировать в .NET? - PullRequest
9 голосов
/ 20 апреля 2010

У меня есть этот код, который сохраняет PDF-файл.

FileStream fs = new FileStream(SaveLocation, FileMode.Create);
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
fs.Flush();
fs.Close();

Работает нормально. Однако иногда он не снимает блокировку сразу, и это вызывает исключения блокировки файлов с функциями, запускаемыми после этого запуска.

Есть ли идеальный способ снять блокировку файла сразу после fs.Close ()

Ответы [ 6 ]

16 голосов
/ 20 апреля 2010

Вот идеал:

using (var fs = new FileStream(SaveLocation, FileMode.Create))
{
    fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}

, что примерно эквивалентно:

FileStream fs =  null;
try
{
    fs = new FileStream(SaveLocation, FileMode.Create);
    fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}
finally
{
    if (fs != null)
    {
        ((IDisposable)fs).Dispose();
    }
}

с использованием , более читабельным.


ОБНОВЛЕНИЕ:

@ aron, теперь, когда я думаю,

File.WriteAllBytes(SaveLocation, result.DocumentBytes);

выглядит даже красивее, чем идеал: -)

5 голосов
/ 20 апреля 2010

Мы видели эту же проблему в производственном процессе с использованием оператора using ().

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

Но дажесо всем антивирусным программным обеспечением в системах с очень высокой нагрузкой и файлами, хранящимися в общих сетевых ресурсах, мы все еще иногда сталкивались с этой проблемой.A, кашель, короткая Thread.Sleep (), кашель, после закрытия, казалось, вылечил его.Если у кого-то есть лучшее решение, я бы с удовольствием его услышал!

3 голосов
/ 20 апреля 2010

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

3 голосов
/ 20 апреля 2010

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

using (FileStream fs = new FileStream(SaveLocation, FileMode.Create))
{
  fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);  
}
1 голос
/ 28 января 2015

Это сработало для меня при использовании .Flush (). Мне пришлось добавить закрытие внутри оператора using.

 using (var imageFile = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite))
 {
     imageFile.Write(bytes, 0, bytes.Length);
     imageFile.Flush();
     imageFile.Close();
  }
0 голосов
/ 29 мая 2019

Просто возникла та же проблема, когда я закрыл FileStream и сразу открыл файл в другом классе. Оператор using не был решением, поскольку FileStream был создан в другом месте и сохранен в списке. Очистка списка была недостаточной.

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

GC.Collect();

сразу после закрытия потока. Это сработало для меня.

Полагаю, что решения Иана Мерсера перевести поток в спящий режим могут иметь тот же эффект, что даст GC время для освобождения ресурсов.

...