gpt4 book ai didi

C# - 检查是否可以访问/读取文件夹

转载 作者:行者123 更新时间:2023-12-05 08:06:35 26 4
gpt4 key购买 nike

在结束我的问题之前,请看看我在这个问题的末尾检查了哪些不起作用


问题

我一直在尝试各种 SO 答案,所有这些都给我带来了一个异常(exception),除了其中许多听起来对于应该非常简单的事情来说过于复杂。

如何在执行之前检查我是否有权枚举文件夹的内容? (我不想尝试/捕获,因为我正在遍历文件系统并且多次尝试/捕获会影响 C# 上的性能)

每当我尝试以下操作时:

//where dir is a DirectoryInfo instance
foreach (FileInfo file in dir.EnumerateFiles())

我得到这个异常:

An unhandled exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
Additional information: O acesso ao caminho 'e:\$RECYCLE.BIN\S-1-5-18' foi negado.
translation:"Access to the path 'e:\$RECYCLE.BIN\S-1-5-18' was denied"


什么不起作用:

1:

当我这样做时,代码进入 if 并在命中枚举时抛出相同的异常。

PermissionSet permissions = new PermissionSet(System.Security.Permissions.PermissionState.None);
permissions.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, dir.FullName));

if (permissions.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))

2:

以下引发异常:

DirectorySecurity security = dir.GetAccessControl(AccessControlSections.All); 

异常(exception):

An unhandled exception of type 'System.Security.AccessControl.PrivilegeNotHeldException' occurred in mscorlib.dll
Additional information: O processo não possui o privilégio 'SeSecurityPrivilege' necessário para esta operação.
translation: The process doesn't have the 'SeSecurityPrivilege' privilege necessary for this operation.

还有:

    DirectorySecurity security = dir.GetAccessControl(AccessControlSections.None); 

异常(exception):

An unhandled exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
Additional information: Tentativa de execução de uma operação não autorizada.
translation: Attempting to execute an unauthorized operation

3:

尝试过:

DirectorySecurity security = Directory.GetAccessControl(dir.FullName);

与上述相同的异常。

最佳答案

这似乎是一个很好的问题,可以发布我的 SafeWalk 类(class),该类(class)将来自多个答案的提示聚集在一起。它能够在我的盒子上遍历 C:\和 D:\而不会造成问题。

public static class SafeWalk {
[Flags]
public enum ReturnOptions {
ReturnFiles = 1, ReturnDirectories = 2, ReturnBoth = 3
}

const string AllFiles = "*.*";

// File and Directory Name Tree Walkers

public static IEnumerable<string> SafeEnumerateFileAndDirNames(this DirectoryInfo di, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
di.FullName.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnBoth);

public static IEnumerable<string> SafeEnumerateFileAndDirNames(this DirectoryInfo di, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
di.FullName.SafeEnumerateFileAndDirNames(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnBoth);

public static IEnumerable<string> SafeEnumerateFileAndDirNames(this DirectoryInfo di, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
di.FullName.SafeEnumerateFileAndDirNames(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnBoth);

public static IEnumerable<string> SafeEnumerateFileAndDirNames(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnBoth);

public static IEnumerable<string> SafeEnumerateFileAndDirNames(this string path, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.SafeEnumerateFileAndDirNames(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnBoth);

public static IEnumerable<string> SafeEnumerateFileAndDirNames(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) {
var searchQueue = new Queue<string>() { path };

while (searchQueue.Count > 0) {
var cdn = searchQueue.Dequeue();

IEnumerable<string> cdiFiles = null;
if (returnOpt.HasFlag(ReturnOptions.ReturnFiles)) {
try {
cdiFiles = Directory.EnumerateFiles(cdn, filePattern, SearchOption.TopDirectoryOnly);
}
catch (Exception) {
}

if (cdiFiles != null)
foreach (var filename in cdiFiles)
yield return filename;
}

if ((!returnOpt.HasFlag(ReturnOptions.ReturnFiles) || cdiFiles != null) && (returnOpt.HasFlag(ReturnOptions.ReturnDirectories) || searchOpt == SearchOption.AllDirectories)) { // skip if file enumeration failed
IEnumerable<string> cdiDirs = null;
try {
cdiDirs = Directory.EnumerateDirectories(cdn, dirPattern, SearchOption.TopDirectoryOnly);
}
catch (Exception) {
}

if (cdiDirs != null) {
foreach (var dirname in cdiDirs) {
if (searchOpt == SearchOption.AllDirectories)
searchQueue.Enqueue(dirname);

if (returnOpt.HasFlag(ReturnOptions.ReturnDirectories))
yield return dirname;
}
}
}
}
}

public static IEnumerable<string> SafeEnumerateFileNames(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnFiles);

public static IEnumerable<string> SafeEnumerateFileNames(this string path, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.SafeEnumerateFileAndDirNames(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnFiles);

public static IEnumerable<string> SafeEnumerateFileNames(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.SafeEnumerateFileAndDirNames(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnFiles);

public static IEnumerable<string> SafeEnumerateFileNames(this DirectoryInfo path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.FullName.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnFiles);

public static IEnumerable<string> SafeEnumerateFileNames(this DirectoryInfo path, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.FullName.SafeEnumerateFileAndDirNames(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnFiles);

public static IEnumerable<string> SafeEnumerateFileNames(this DirectoryInfo path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.FullName.SafeEnumerateFileAndDirNames(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnFiles);

public static IEnumerable<string> SafeEnumerateDirectoryNames(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnDirectories);

public static IEnumerable<string> SafeEnumerateDirectoryNames(this string path, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.SafeEnumerateFileAndDirNames(AllFiles, dirPattern, searchOpt, ReturnOptions.ReturnDirectories);

public static IEnumerable<string> SafeEnumerateDirectoryNames(this DirectoryInfo path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.FullName.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnDirectories);

public static IEnumerable<string> SafeEnumerateDirectoryNames(this DirectoryInfo path, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
path.FullName.SafeEnumerateFileAndDirNames(AllFiles, dirPattern, searchOpt, ReturnOptions.ReturnDirectories);

// File and Directory Info Tree Walkers

public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
new DirectoryInfo(path).SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, returnOpt);

public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this string path, string searchPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
new DirectoryInfo(path).SafeEnumerateFileSystemInfos(searchPattern, searchPattern, searchOpt, returnOpt);

public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
new DirectoryInfo(path).SafeEnumerateFileSystemInfos(filePattern, dirPattern, searchOpt, returnOpt);

public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this DirectoryInfo di, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
di.SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, returnOpt);

public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this DirectoryInfo di, string searchPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
di.SafeEnumerateFileSystemInfos(searchPattern, searchPattern, searchOpt, returnOpt);

public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this DirectoryInfo di, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) {
var searchQueue = new Queue<DirectoryInfo>();
searchQueue.Enqueue(di);
while (searchQueue.Count > 0) {
var cdi = searchQueue.Dequeue();

IEnumerable<string> cdiFiles = null;
if (returnOpt.HasFlag(ReturnOptions.ReturnFiles)) {
try {
cdiFiles = Directory.EnumerateFiles(cdi.FullName, filePattern, SearchOption.TopDirectoryOnly);
}
catch (Exception) {
}

if (cdiFiles != null) {
var cfis = new ConcurrentBag<FileInfo>();
cdiFiles.AsParallel()
.ForAll(f => {
try {
cfis.Add(new FileInfo(f));
}
catch (Exception) {
}
});

foreach (var fi in cfis)
yield return fi;
}
}

if ((!returnOpt.HasFlag(ReturnOptions.ReturnFiles) || cdiFiles != null) && (returnOpt.HasFlag(ReturnOptions.ReturnDirectories) || searchOpt.HasFlag(SearchOption.AllDirectories))) { // skip if file enumeration failed
IEnumerable<string> cdiDirs = null;
try {
cdiDirs = Directory.EnumerateDirectories(cdi.FullName, dirPattern, SearchOption.TopDirectoryOnly);
}
catch (Exception) {
}

if (cdiDirs != null) {
var cdis = new ConcurrentBag<DirectoryInfo>();
cdiDirs.AsParallel()
.ForAll(d => {
try {
cdis.Add(new DirectoryInfo(d));
}
catch (Exception) {
}
});
foreach (var rdi in cdis) {
if (returnOpt.HasFlag(ReturnOptions.ReturnDirectories))
yield return rdi;
if (searchOpt == SearchOption.AllDirectories)
searchQueue.Enqueue(rdi);
}
}
}
}
}

public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
new DirectoryInfo(path).SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this string path, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
new DirectoryInfo(path).SafeEnumerateFileSystemInfos(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
new DirectoryInfo(path).SafeEnumerateFileSystemInfos(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this DirectoryInfo di, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
di.SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this DirectoryInfo di, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
di.SafeEnumerateFileSystemInfos(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this DirectoryInfo di, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
di.SafeEnumerateFileSystemInfos(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

public static IEnumerable<DirectoryInfo> SafeEnumerateDirectoryInfos(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
new DirectoryInfo(path).SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnDirectories).Cast<DirectoryInfo>();

public static IEnumerable<DirectoryInfo> SafeEnumerateDirectoryInfos(this string path, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
new DirectoryInfo(path).SafeEnumerateFileSystemInfos(AllFiles, dirPattern, searchOpt, ReturnOptions.ReturnDirectories).Cast<DirectoryInfo>();

public static IEnumerable<DirectoryInfo> SafeEnumerateDirectoryInfos(this DirectoryInfo di, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
di.SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnDirectories).Cast<DirectoryInfo>();

public static IEnumerable<DirectoryInfo> SafeEnumerateDirectoryInfos(this DirectoryInfo di, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
di.SafeEnumerateFileSystemInfos(AllFiles, dirPattern, searchOpt, ReturnOptions.ReturnDirectories).Cast<DirectoryInfo>();
}

关于C# - 检查是否可以访问/读取文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60194501/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com