c# – 可以使用FileShare.Delete导致UnauthorizedAccessException吗?

我正在使用以下代码打开一个文件,用于读取我之前在用户的%TEMP%文件夹中创建的文件
new FileStream(cacheFileName,FileMode.Open,FileAccess.Read,FileShare.Read | FileShare.Delete);

在某些用户的计算机上,这有时会抛出UnauthorizedAccessException,并显示消息“访问路径…被拒绝”.我无法重现这一点.我最初的猜测是反病毒或索引引擎正在做一些时髦的事情,但我也注意到这段代码正在使用“FileShare.Delete”,我不确定应该在那里.

是否存在使用“FileShare.Delete”导致UnauthorizedAccessException的情况?

解决方法

是的,FileShare.Delete往往会导致此问题.由在后台运行的任何程序使用,扫描文件,文件索引器和病毒扫描程序是常见示例.

FileShare.Delete允许其他进程删除文件,即使后台进程仍然打开了文件并正在从中读取.其他进程将忘记文件实际上没有消失,因为它知道文件实际上已被删除.

当其他进程依赖于实际被删除文件并执行其他操作时,麻烦就开始了.通常通过创建具有相同名称的新文件来触发.值得注意的是,保存文件是一种非常不明智的方法,因为当保存失败时,如果没有备份就会导致完全数据丢失,但这种错误很常见.

这将失败,因为该文件的目录条目仍然存在,它将不会消失,直到打开文件的最后一个进程关闭句柄.尝试再次打开文件的任何其他进程将被错误5,“访问被拒绝”.包括删除文件并尝试重新创建文件的进程.

解决方法是始终使用“事务”保存,在尝试覆盖之前重命名文件.在.NET中使用File.Replace(),在带有ReplaceFile()的本机winapi中.手动也很容易,工作流程是:

>删除备份文件,如果失败则停止
>将旧文件重命名为备份文件名,如果失败则停止
>使用原始文件名写入新文件,如果失败则重命名备份
>删除备份文件,忽略失败

步骤2确保永远不会有任何数据丢失,如果出现任何问题,原始文件将保持不变.步骤4确保FileShare.Delete按预期工作,当其他进程关闭其句柄时,该备份文件最终将消失.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...