C # Linq для файлов, к которым у пользователя есть доступ на чтение - PullRequest
4 голосов
/ 22 сентября 2011

Как бы я использовал Linq на list.Items = directoryInfo.GetFiles("\\server\share\folder\"); для включения только тех файлов, к которым у пользователя есть права на чтение?

... Пока что только предложения используют try / catches или API, в которых устарелиNET 4.0?Я предпочел бы что-нибудь прочитать ACL и посмотреть, был ли предоставлен доступ для чтения конкретному пользователю или группе, членом которой он является.Я пытаюсь сделать это для упрощенного управления предоставлением отчетов пользователям на веб-сайте, который не будет иметь большой трафик, поэтому логика, которая гласит: «кто знает, можете ли вы действительно прочитать его при попытке открыть файл», неотносятся к этому делу.Я чувствую, что Microsoft действительно должна облегчить эту задачу.

Ответы [ 4 ]

1 голос
/ 22 сентября 2011

просто попробуйте это. Должно работать. Не проверено, хотя

  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 голос
/ 22 сентября 2011

Вы рискуете испытать состояние гонки, если проверяете разрешение на чтение до открытия файла.

Если вы пытаетесь прочитать все файлы, к которым у вас есть доступ, в папке, лучшепросто попробуйте открыть каждый и поймать UnauthorizedAccessException.

См .:

0 голосов
/ 22 сентября 2011

Протестировано и работает, но вернет 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;
}
0 голосов
/ 22 сентября 2011

Примечание: я не проверял, но теоретически это должно работать

Сначала определите предикат для определения доступа на чтение

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

<ч /> Тогда это должен быть простой случай использования предложения where в запросе linq

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