Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. ОБНОВЛЕНИЕ:
Измененный код на основе этот ответ для избавлений от устаревших методов.
можно использовать пространство имен безопасности для проверки этого:
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
}
}
До получения тех разрешение, Вы оказываетесь перед необходимостью просить, чтобы пользователь сделал это для Вас так или иначе. Если бы Вы могли бы программно сделать это, то мы все были бы в беде;)
Когда Ваш код делает следующее:
Вы выполняете риск, что полномочия изменяются между 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 ). Другие ответы на Переполнении стека и более широкой сети рекомендуют пытаться выполнить действие, чтобы знать, позволяется ли разрешение. Это развешивает суммы, что требуется, чтобы реализовывать вычисление разрешения и должно быть достаточно для откладывания Вас от выполнения этого.
Вы можете попробовать следующий блок кода, чтобы проверить, имеет ли каталог доступ на запись.
Он проверяет 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
}
Извините, но ни одно из предыдущих решений мне не помогло. Мне нужно проверить обе стороны: разрешения 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!