我如何在list.Items = directoryInfo.GetFiles("\\server\share\folder\");
上使用Linq仅包含用户具有读取权限的文件?
... 到目前为止,只有建议使用try / catches或.NET 4.0中已过时的API?我更喜欢读取ACL的内容,看看特定用户或用户所属的组是否已被授予读访问权限。我正在尝试这样做,以便简化管理,向网站上的用户授予报告,这些网站的流量不会很高,因此“当您尝试打开文件时,谁知道您是否可以实际读取”的逻辑不会属于这种情况。我觉得微软真的应该让这项工作变得更容易。
答案 0 :(得分:1)
试试这个。应该工作。虽然没有测试
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
答案 1 :(得分:1)
如果在打开文件之前检查读取权限,则存在竞争条件的风险。
如果您尝试阅读文件夹中有权访问的所有文件,最好只是尝试打开每个文件并抓住UnauthorizedAccessException
。
请参阅:
答案 2 :(得分:0)
注意:我没有测试过,但理论上它应该可以运行
首先,定义谓词以确定读取访问权限
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;
答案 3 :(得分:0)
经过测试和工作,但如果文件正在使用中则返回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;
}