gpt4 book ai didi

c# - Directory.EnumerateFiles 搜索模式不适用于文件共享

转载 作者:行者123 更新时间:2023-12-03 16:10:06 25 4
gpt4 key购买 nike

根据Microsoft Docs site for Directory.EnumerateFiles ,搜索模式参数将匹配任何以指定模式开头的扩展名,只要它正好是 3 个字符。但是,这不适用于文件共享,仅适用于本地驱动器。
对于 \\share\folder\ 的目录包含一个名为 file.xlsx 的文件,第一个代码片段不会返回它:

public static List<string> GetAllFilesFromDirectory(string directory) =>
new[] { "*.csv", "*.xls", "*.txt" }.SelectMany(ext => Directory.EnumerateFiles(directory, ext)).ToList();
但是,如果我添加 *.xlsx模式,它确实返回它:
public static List<string> GetAllFilesFromDirectory(string directory) =>
new[] { "*.csv", "*.xls", "*.xlsx", "*.txt" }.SelectMany(ext => Directory.EnumerateFiles(directory, ext)).ToList();
我还使用 C:\temp 中的相同文件对此进行了测试。目录,它发现它以两种方式返回。
这是在 .NET Framework 4.7.2 控制台应用程序中运行的。
我在搜索模式中遗漏了什么吗?或者这与本地驱动器的文件共享方式不同吗?这会是意料之中的吗?

最佳答案

你一定是最不幸的人,遇到了这个错误。我可以确认它的行为符合您的观察,并且在互联网上的任何地方都找不到任何对此的引用。
于是我追踪了.NET源代码,看看如何Directory.EnumerateFiles工作和 - 在肠道深处 - 最终遇到了 callFindFirstFile及后续 FindNextFile调用。这些是直接从内核 PInvoked 的,所以你不能得到比这更低的。

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);
那么得测试一下。你猜怎么着?它在本地目录中捕获 XLSX 文件,但不在网络共享中。
The doc for the function也没有提到这种行为。是的。您刚刚遇到了一个未记录的“功能”:)
编辑:这变得更好了。看起来像在 .NET 核心 (从 2.0 一直到 .NET 5)这种行为不再存在。他们实际上是自己写的 pattern matcher这一次。 *.xls不会在本地或其他任何文件夹中捕获 XLSX。还有 their documentation还是说应该。
编辑 2021 : doco 现在是 updated评论一下 .NET Framework 上的怪癖。

这是我对 FindFirstFile 的测试代码称呼:
public class Program
{
public static void Main(string[] args)
{
// Ensure these test folders only contain ONE file.
// Name the file "Test.xlsx"
Test(@"C:\Temp\*.xls"); // Finds the xlsx file just fine
Test(@"\\Server\Temp\*.xls"); // But not here!
}

public static void Test(string fileName)
{
Win32Native.WIN32_FIND_DATA data;
var hnd = Win32Native.FindFirstFile(fileName, out data);

if (hnd == Win32Native.InvalidPtr)
Debug.WriteLine("Not found!!");
else
Debug.WriteLine("Found: " + data.cFileName);
}
}

/** Windows native Pinvoke **/
public class Win32Native
{
public static IntPtr InvalidPtr = new IntPtr(-1);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct WIN32_FIND_DATA
{
public uint dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
}

关于c# - Directory.EnumerateFiles 搜索模式不适用于文件共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64564664/

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