我有这个保存pdf文件的代码。
FileStream fs = new FileStream(SaveLocation, FileMode.Create);
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
fs.Flush();
fs.Close();
它工作正常。但是,有时它不会立即释放锁,这会导致文件锁定异常,函数在此运行后运行。
是否有一种理想的方法可以在fs.Close()之后立即释放文件锁
我有这个保存pdf文件的代码。
FileStream fs = new FileStream(SaveLocation, FileMode.Create);
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
fs.Flush();
fs.Close();
它工作正常。但是,有时它不会立即释放锁,这会导致文件锁定异常,函数在此运行后运行。
是否有一种理想的方法可以在fs.Close()之后立即释放文件锁
这是理想的:
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);
看起来比理想的更漂亮:-)
我们已经在生产环境中看到了同样的问题,其中使用了 using() 语句来包装它。
这里的罪魁祸首之一是防病毒软件,它可以在文件关闭后潜入,在释放之前抓住它以检查它是否包含病毒。
但是,即使所有防病毒软件都不在混合中,在文件存储在网络共享上的负载非常高的系统中,我们仍然偶尔会看到问题。A、咳咳,短Thread.Sleep(),咳咳,关闭后好像治好了。如果有人有更好的解决方案,我很想听听!
如果在此之后运行的函数是同一应用程序的一部分,那么更好的方法可能是在整个过程开始时打开文件进行读/写,然后将文件传递给每个函数而不关闭它,直到过程结束。那么应用程序就没有必要阻塞等待 IO 操作完成。
我无法想象为什么在文件关闭后会保持锁定。但是您应该考虑将其包装在 using 语句中,以确保即使引发异常也关闭文件
using (FileStream fs = new FileStream(SaveLocation, FileMode.Create))
{
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}
这在使用 .Flush() 时对我有用,我必须在 using 语句中添加关闭。
using (var imageFile = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite))
{
imageFile.Write(bytes, 0, bytes.Length);
imageFile.Flush();
imageFile.Close();
}
当我关闭 FileStream 并立即在另一个类中打开文件时遇到了同样的问题。using 语句不是解决方案,因为 FileStream 已在另一个地方创建并存储在列表中。清除列表是不够的。
看起来流需要由垃圾收集器释放,然后才能重用文件。如果关闭和打开之间的时间太短,您可以使用
GC.Collect();
在您关闭流之后。这对我有用。
我猜 Ian Mercer 让线程休眠的解决方案可能具有相同的效果,让 GC 有时间释放资源。