LOCALAPPDATA 中的 File.ReadAllBytes UnauthorizedAccessException“对路径的访问被拒绝”

2024-05-07

同一用户在同一台​​机器上读取文件时,会间歇性地发生此异常%LOCALAPPDATA%.

Research

我已经检查了该标题当前提供的所有可能的重复项(有很多)。有一个与读取 AES 加密文件 https://stackoverflow.com/questions/22943631/access-to-the-path-is-denied-on-file-readallbytes-on-aes-encrypted-file没有答案;我不认为适用,因为这些文件没有加密。

其中大多数与写入文件有关(但我正在读取文件),或者是 MSDN 上记录的明显原因文件.ReadAllBytes(字符串) https://msdn.microsoft.com/en-us/library/system.io.file.readallbytes(v=vs.110).aspx.

对此异常的三种解释是:

  1. “当前平台不支持此操作” - 我不知道这是什么意思;但考虑到这有时适用于同一台机器上的同一用户(我将在下面解释),我想我可以排除这种情况。
  2. "path指定了一个目录” - 正如您从下面的代码中看到的,调用是在以下检查中进行的File.Exists,所以我想我可以排除这个可能性。
  3. “调用者没有所需的权限。”这是对此异常的通常解释,我怀疑我遇到了某种“边缘案例”。

Scenario

当以域用户身份运行的应用程序正在读取以下子文件夹内的文件时,就会发生这种情况%LOCALAPPDATA%同一用户的(该用户读取文件不应该有权限问题)。其中的子文件夹仅遵循正常的“CompanyName”\“ApplicationName”结构,并且没有对子文件夹应用其他权限(我们只是使用该文件夹来使我们的文件远离其他人的文件)。

例外

System.UnauthorizedAccessException:访问路径'[已编辑]' 是 否认。在 System.IO.__Error.WinIOError(Int32 errorCode, 字符串 也许FullPath)在System.IO.FileStream.Init(字符串路径,FileMode 模式、FileAccess 访问、Int32 权限、布尔 useRights、FileShare 共享、Int32 bufferSize、FileOptions 选项、SECURITY_ATTRIBUTES secAttrs、字符串 msgPath、布尔值 bFromProxy、布尔值 useLongPath、 Boolean checkHost) at System.IO.FileStream..ctor(字符串路径, FileMode 模式、FileAccess 访问、FileShare 共享、Int32 bufferSize、 FileOptions 选项、字符串 msgPath、布尔值 bFromProxy、布尔值 useLongPath, 布尔值 checkHost) at System.IO.File.InternalReadAllBytes(字符串路径,布尔值checkHost)
at 下面的代码

Code

        // Note that filename is within %LOCALAPPDATA%
        if (File.Exists(fileName))
        {
            var readAllBytes = File.ReadAllBytes(fileName); // exception here
            // etc...
        }

证明它是间歇性的

我可以结合我们的错误日志和其他信息来证明这是有效的most当时,我可以证明机器和用户的特定组合的以下事件序列:

  • 应用程序可以运行,然后
  • 这种异常发生(可能会发生几次,每次重试延迟呈指数增长:1分钟、2分钟、4分钟等),然后
  • 该应用程序再次运行

我不认为文件系统会发生任何重大更改(例如权限)来修复它。我想知道这是否可能是由边缘权限问题引起的,例如,如果他们的密码即将过期或最近已更改。

我有一个具体的例子,当我注意到这个错误发生时,我建议用户重新启动他们的机器,然后问题就消失了。

Question

任何人都可以给我一个关于其原因的权威解释,高于我已经猜测的内容,或者确认它是什么?


这个问题太广泛了,但我想指出,除了您列出的之外,还有其他原因导致访问被拒绝异常。例如,考虑这个简单的程序:

public class Program {
    static string _target = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "test", "test.txt");
    static void Main(string[] args) {
        File.Create(_target).Dispose();
        ProcessFile();

        // below throws access denied
        if (File.Exists(_target))
            Console.WriteLine(File.ReadAllText(_target));
        Console.ReadKey();
    }

    static void ProcessFile() {
        // open and abandon handle
        var fs = new FileStream(_target, FileMode.Open, FileAccess.Read, FileShare.Delete);
        // delete
        File.Delete(_target);
    }        
}  

这里我们在下面创建新文件%LOCALAPPDATA%,然后打开它FileShare.Delete,但不关闭。FileShare.Delete允许随后删除该文件,但在关闭该文件的所有句柄之前,该文件不会被实际删除。

然后我们继续File.Delete,它实际上并没有删除文件,而是将其标记为删除,因为我们仍然有打开的文件句柄。

Now, File.Exists对于此类文件返回 true,但尝试访问它会抛出“访问被拒绝”异常,如您所描述的。

很难判断这种具体情况是否与您的情况相关,但可能是。

我的观点主要是:您应该预料到此类异常(以及“文件已在使用”类型的异常)并通过重试来处理它们。它们的发生可能出于您无法控制的各种原因。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LOCALAPPDATA 中的 File.ReadAllBytes UnauthorizedAccessException“对路径的访问被拒绝” 的相关文章

随机推荐