FileStream 保存文件然后立即在.NET 中解锁?

发布于 2024-08-29 10:24:10 字数 327 浏览 10 评论 0原文

我有这段代码可以保存pdf文件。

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

效果很好。然而,有时它不会立即释放锁,这会导致文件锁定异常,并且在该函数运行后运行。

有没有一种理想的方法可以在fs.Close()之后立即释放文件锁定

I have this code that saves a pdf file.

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

It works fine. However sometimes it does not release the lock right away and that causes file locking exceptions with functions run after this one run.

Is there a ideal way to release the file lock right after the fs.Close()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

你如我软肋 2024-09-05 10:24:10

这是理想的:

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);

看起来比理想的更漂亮:-)

Here's the ideal:

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

which is roughly equivalent to:

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();
    }
}

the using being more readable.


UPDATE:

@aron, now that I'm thinking

File.WriteAllBytes(SaveLocation, result.DocumentBytes);

looks even prettier to the eye than the ideal :-)

独木成林 2024-09-05 10:24:10

我们在生产环境中也看到了同样的问题,并用 using() 语句包装了它。

这里的罪魁祸首之一是防病毒软件,它可以在文件关闭后潜入,抓住它以检查它是否包含病毒,然后再释放它。

但即使将所有防病毒软件排除在外,在文件存储在网络共享上的负载非常高的系统中,我们仍然偶尔会遇到该问题。 A,咳,短Thread.Sleep(),咳,close后好像能治好。如果有人有更好的解决方案,我很想听听!

We have seen this same issue in production with a using() statement wrapping it.

One of the top culprits here is anti-virus software which can sneak in after the file is closed, grab it to check it doesn't contain a virus before releasing it.

But even with all anti-virus software out of the mix, in very high load systems with files stored on network shares we still saw the problem occasionally. A, cough, short Thread.Sleep(), cough, after the close seemed to cure it. If someone has a better solution I'd love to hear it!

茶花眉 2024-09-05 10:24:10

我无法想象为什么在文件关闭后仍会保持锁定。但是您应该考虑将其包装在 using 语句中,以确保即使引发异常也能关闭文件

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

I can't imagine why the lock would be maintained after the file is closed. But you should consider wrapping this in a using statment to ensure that the file is closed even if an exception is raised

using (FileStream fs = new FileStream(SaveLocation, FileMode.Create))
{
  fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);  
}
这样的小城市 2024-09-05 10:24:10

如果在此之后运行的函数是同一应用程序的一部分,那么更好的方法可能是在整个进程开始时打开文件进行读/写,然后将文件传递给每个函数而不关闭它,直到流程结束。那么应用程序就不需要阻塞等待 IO 操作完成。

If the functions that run after this one are part of the same application, then a better approach might be to open the file for read/write at the beginning of the entire process, and then pass the file to each function without closing it until the end of the process. Then it will be unnecessary for the application to block waiting for the IO operation to complete.

九八野马 2024-09-05 10:24:10

当使用 .Flush() 时,这对我有用,我必须在 using 语句中添加关闭。

 using (var imageFile = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite))
 {
     imageFile.Write(bytes, 0, bytes.Length);
     imageFile.Flush();
     imageFile.Close();
  }

This worked for me when using .Flush() I had to add a close inside the using statement.

 using (var imageFile = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite))
 {
     imageFile.Write(bytes, 0, bytes.Length);
     imageFile.Flush();
     imageFile.Close();
  }
掩于岁月 2024-09-05 10:24:10

当我关闭 FileStream 并立即在另一个类中打开文件时,遇到了同样的问题。 using 语句不是解决方案,因为 FileStream 是在另一个位置创建并存储在列表中的。清除清单还不够。

看起来流需要由垃圾收集器释放才能重用文件。如果关闭和打开之间的时间太短,您可以

GC.Collect();

在关闭流后立即使用。这对我有用。

我猜想 Ian Mercer 将线程置于睡眠状态的解决方案可能具有相同的效果,为 GC 提供时间来释放资源。

Just had the same issue when I closed a FileStream and opened the file immediately in another class. The using statement was not a solution since the FileStream had been created at another place and stored in a list. Clearing the list was not enough.

It looks like the stream needs to be freed by the garbage collector before the file can be reused. If the time between closing and opening is too short, you can use

GC.Collect();

right after you closed the stream. This worked for me.

I guess the solutions of Ian Mercer to put the thread to sleep might have the same effect, giving the GC time to free the resources.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文