Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Linq用于用户具有读取权限的文件_C#_Linq_File Permissions_Acl - Fatal编程技术网

C#Linq用于用户具有读取权限的文件

C#Linq用于用户具有读取权限的文件,c#,linq,file-permissions,acl,C#,Linq,File Permissions,Acl,如何在list.Items=directoryInfo.GetFiles(“\\server\share\folder\”)上使用Linq是否仅包括用户具有读取权限的文件 。。。 到目前为止,只有建议使用try/catch,或者在.NET4.0中过时的API?我更喜欢阅读ACL,看看用户所属的特定用户或组是否已被授予读取权限。我尝试这样做是为了简化管理,在一个流量不高的网站上向用户授予报告,所以“谁知道当你试图打开文件时你是否真的可以阅读它”的逻辑不适用于这种情况。我觉得微软真的应该让这项任务变

如何在
list.Items=directoryInfo.GetFiles(“\\server\share\folder\”)上使用Linq
是否仅包括用户具有读取权限的文件

。。。
到目前为止,只有建议使用try/catch,或者在.NET4.0中过时的API?我更喜欢阅读ACL,看看用户所属的特定用户或组是否已被授予读取权限。我尝试这样做是为了简化管理,在一个流量不高的网站上向用户授予报告,所以“谁知道当你试图打开文件时你是否真的可以阅读它”的逻辑不适用于这种情况。我觉得微软真的应该让这项任务变得更容易。

注意:我还没有测试过它,但理论上它应该可以工作

首先,定义一个谓词来确定读访问

bool CanRead(FileInfo file)
{
  try {
    file.GetAccessControl();
    //Read and write access;
    return true;
  }
  catch (UnauthorizedAccessException uae)
  {
    if (uae.Message.Contains("read-only"))
    {
      //read-only access
      return true;
    }
    return false;
  }
}

然后,应该是在linq查询中使用where子句的简单情况

from file in directoryInfo.GetFiles("\\server\share\folder\") 
  where HaveAccess(f) == true
    select f;

试试这个。应该可以。不过还没有测试过

  var fw = from f in new DirectoryInfo("C:\\Users\\User\\Downloads\\").GetFiles()
                where SecurityManager.IsGranted(new FileIOPermission
 (FileIOPermissionAccess.Write, f.FullName))
                select f;
编辑如果只是只读文件,请尝试此操作

var fe = from f in new DirectoryInfo("C:\\Users\\ashley\\Downloads\\").GetFiles()
                where f.IsReadOnly==true
                select f

如果在打开文件之前检查读取权限,则可能会发生争用情况

如果您试图读取文件夹中您有权访问的所有文件,最好只打开每个文件并捕获
UnauthorizedAccessException

见:


已测试并正常工作,但如果文件正在使用,将返回false

void Main()
{
    var directoryInfo = new DirectoryInfo(@"C:\");
    var currentUser = WindowsIdentity.GetCurrent();
    var files = directoryInfo.GetFiles(".").Where(f => CanRead(currentUser, f.FullName));
}

private bool CanRead(WindowsIdentity user, string filePath)
{
    if(!File.Exists(filePath))
        return false;

    try
    {
        var fileSecurity = File.GetAccessControl(filePath, AccessControlSections.Access); 
        foreach(FileSystemAccessRule fsRule in fileSecurity.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier)))
        {
            foreach(var usrGroup in user.Groups)
            {
                if(fsRule.IdentityReference.Value == usrGroup.Value)
                    return true;
            }
        }
    } catch (InvalidOperationException) {
        //File is in use
        return false;
    }

    return false;
}

这是否适用于组内的组?显式拒绝权限怎么样?你可能可以。是的..但是在catch中声明一些逻辑听起来不是很简单。假设你有数千个文件,等待异常发生以获取其状态是非常昂贵的操作。@Ashley:那些try/catch我很确定是特例(驱动器不存在,或者您完全被锁定在文件夹之外)。您可以从Linq查询中调用该函数,这样您的高级代码仍然可以是漂亮的。它已经封装了true/false,所以您只需要将其插入
where
子句中。我不知道是否有更好的选项不使用p/Invoke(例如,
Try
variant)。此外,我认为枚举文件系统上的文件可能已经是一个瓶颈。我推测,在这一点上,异常可以忽略不计。