Как Вы проверяете на полномочия записать в каталог или файл?

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

59
задан Imran Ali Khan 25 June 2015 в 09:14
поделиться

4 ответа

ОБНОВЛЕНИЕ:

Измененный код на основе этот ответ для избавлений от устаревших методов.

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

public void ExportToFile(string filename)
{
    var permissionSet = new PermissionSet(PermissionState.None);    
    var writePermission = new FileIOPermission(FileIOPermissionAccess.Write, filename);
    permissionSet.AddPermission(writePermission);

    if (permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))
    {
        using (FileStream fstream = new FileStream(filename, FileMode.Create))
        using (TextWriter writer = new StreamWriter(fstream))
        {
            // try catch block for write permissions 
            writer.WriteLine("sometext");


        }
    }
    else
    {
        //perform some recovery action here
    }

}

До получения тех разрешение, Вы оказываетесь перед необходимостью просить, чтобы пользователь сделал это для Вас так или иначе. Если бы Вы могли бы программно сделать это, то мы все были бы в беде;)

66
ответ дан Community 24 November 2019 в 18:18
поделиться

Когда Ваш код делает следующее:

  1. Проверки у текущего пользователя есть разрешение сделать что-то.
  2. Выполняет действие, для которого нужны права, зарегистрировался 1.

Вы выполняете риск, что полномочия изменяются между 1 и 2 , потому что Вы не можете предсказать то, что еще будет происходить в системе во времени выполнения. Поэтому Ваш код должен обработать ситуацию, где UnauthorisedAccessException брошен даже при предыдущей проверке полномочий.

Примечание, что класс SecurityManager используется для проверки полномочий CAS и на самом деле не сверяется с ОС, есть ли у текущего пользователя доступ для записи к указанному местоположению (через ACLs и ТУЗЫ). По сути, IsGranted будет всегда возвращать true для локально запущенных приложений.

Пример (полученный от пример Josh's ):

//1. Provide early notification that the user does not have permission to write.
FileIOPermission writePermission = new FileIOPermission(FileIOPermissionAccess.Write, filename);
if(!SecurityManager.IsGranted(writePermission))
{
    //No permission. 
    //Either throw an exception so this can be handled by a calling function
    //or inform the user that they do not have permission to write to the folder and return.
}

//2. Attempt the action but handle permission changes.
try
{
    using (FileStream fstream = new FileStream(filename, FileMode.Create))
    using (TextWriter writer = new StreamWriter(fstream))
    {
        writer.WriteLine("sometext");
    }
}
catch (UnauthorizedAccessException ex)
{
    //No permission. 
    //Either throw an exception so this can be handled by a calling function
    //or inform the user that they do not have permission to write to the folder and return.
}

Это хитро и не рекомендуемый , чтобы попытаться программно вычислить эффективные полномочия от папки на основе необработанного ACLs (которые являются всем, что доступно через Система. Безопасность. Классы AccessControl ). Другие ответы на Переполнении стека и более широкой сети рекомендуют пытаться выполнить действие, чтобы знать, позволяется ли разрешение. Это развешивает суммы, что требуется, чтобы реализовывать вычисление разрешения и должно быть достаточно для откладывания Вас от выполнения этого.

30
ответ дан Community 24 November 2019 в 18:18
поделиться

Вы можете попробовать следующий блок кода, чтобы проверить, имеет ли каталог доступ на запись.

Он проверяет FileSystemAccessRule.

           string directoryPath = "C:\\XYZ"; //folderBrowserDialog.SelectedPath;
           bool isWriteAccess = false;
           try
           {
              AuthorizationRuleCollection collection = Directory.GetAccessControl(directoryPath).GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
              foreach (FileSystemAccessRule rule in collection)
              {
                 if (rule.AccessControlType == AccessControlType.Allow)
                 {
                    isWriteAccess = true;
                    break;
                 }
              }
           }
           catch (UnauthorizedAccessException ex)
           {
              isWriteAccess = false;
           }
           catch (Exception ex)
           {
              isWriteAccess = false;
           }
           if (!isWriteAccess)
           {
             //handle notifications                 
           }
2
ответ дан 24 November 2019 в 18:18
поделиться

Извините, но ни одно из предыдущих решений мне не помогло. Мне нужно проверить обе стороны: разрешения SecurityManager и SO. Я многому научился с кодом Джоша и с ответом iain, но, боюсь, мне нужно использовать код Ракеша (также благодаря ему). Только одна ошибка: я обнаружил, что он проверяет только разрешения «Разрешить», а не «Запретить». Итак, мое предложение:

        string folder;
        AuthorizationRuleCollection rules;
        try {
            rules = Directory.GetAccessControl(folder)
                .GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
        } catch(Exception ex) { //Posible UnauthorizedAccessException
            throw new Exception("No permission", ex);
        }

        var rulesCast = rules.Cast<FileSystemAccessRule>();
        if(rulesCast.Any(rule => rule.AccessControlType == AccessControlType.Deny)
            || !rulesCast.Any(rule => rule.AccessControlType == AccessControlType.Allow))
            throw new Exception("No permission");

        //Here I have permission, ole!
6
ответ дан 24 November 2019 в 18:18
поделиться