gpt4 book ai didi

c# - 获取所有目录并捕获权限异常并继续

转载 作者:行者123 更新时间:2023-11-30 20:55:06 26 4
gpt4 key购买 nike

public void newestFile(string path)
{
try
{
foreach (var item in dir.GetDirectories("*.*", SearchOption.AllDirectories))
{
var file = item.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
}
}
catch (Exception ex)
{

}
}

我想从特定路径的每个目录中获取最新文件,并在捕获权限异常后继续,目前我的代码卡在捕获中,无法继续。

最佳答案

不幸的是,Microsoft 的 GetDirectories() 实现非常差,并且不处理与访问权限相关的 IO 异常。

如果您只想跳过您无权访问的目录(例如特殊的 Recycle Bin 文件夹),那么您必须为 Windows 编写自己的包装器API 函数 FindFirstFile()FindNextFile()

这是一个完整的例子。如果你运行它,你会看到它列出了 C: 驱动器上的所有可访问目录。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;

namespace Demo
{
public class Program
{
private void run()
{
string root = "C:\\";

foreach (var folder in FolderEnumerator.EnumerateFoldersRecursively(root))
Console.WriteLine(folder);
}

private static void Main()
{
new Program().run();
}
}

public static class FolderEnumerator
{
public static IEnumerable<string> EnumerateFoldersRecursively(string root)
{
foreach (var folder in EnumerateFolders(root))
{
yield return folder;

foreach (var subfolder in EnumerateFoldersRecursively(folder))
yield return subfolder;
}
}

public static IEnumerable<string> EnumerateFolders(string root)
{
WIN32_FIND_DATA findData;
string spec = Path.Combine(root, "*");

using (SafeFindHandle findHandle = FindFirstFile(spec, out findData))
{
if (!findHandle.IsInvalid)
{
do
{
if ((findData.cFileName != ".") && (findData.cFileName != "..")) // Ignore special "." and ".." folders.
{
if ((findData.dwFileAttributes & FileAttributes.Directory) != 0)
{
yield return Path.Combine(root, findData.cFileName);
}
}
}
while (FindNextFile(findHandle, out findData));
}
}
}

internal sealed class SafeFindHandle: SafeHandleZeroOrMinusOneIsInvalid
{
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]

public SafeFindHandle(): base(true)
{
}

protected override bool ReleaseHandle()
{
if (!IsInvalid && !IsClosed)
{
return FindClose(this);
}

return (IsInvalid || IsClosed);
}

protected override void Dispose(bool disposing)
{
if (!IsInvalid && !IsClosed)
{
FindClose(this);
}

base.Dispose(disposing);
}
}

[StructLayout(LayoutKind.Sequential)]
internal struct FILETIME
{
public uint dwLowDateTime;
public uint dwHighDateTime;

public long ToLong()
{
return dwLowDateTime + ((long)dwHighDateTime) << 32;
}
};

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]

internal struct WIN32_FIND_DATA
{
public FileAttributes dwFileAttributes;
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public int nFileSizeHigh;
public int nFileSizeLow;
public int dwReserved0;
public int dwReserved1;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
public string cFileName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_ALTERNATE)]
public string cAlternate;
}

[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern SafeFindHandle FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);

[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FindNextFile(SafeHandle hFindFile, out WIN32_FIND_DATA lpFindFileData);

[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FindClose(SafeHandle hFindFile);

private const int MAX_PATH = 260;
private const int MAX_ALTERNATE = 14;
}
}

注意:此代码使用 FindFirstFile()FindNextFile() 循环遍历所有文件夹和文件。上面的代码只是忽略文件,只返回文件夹。

使用FindFirstFileEx()会更有效率并指定一个标志以仅返回目录。我把这个变化留给读者作为众所周知的练习。 ;)

关于c# - 获取所有目录并捕获权限异常并继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18527170/

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