在编程过程中,可能会遇到一些不常见但可能引发问题的情况。例如,使用GetFiles()方法时,如果搜索通配符包含星号(*)并且文件扩展名为三字符长(如*.xml或*.jpg),GetFiles()方法会返回所有以提供的扩展名开始的文件。这意味着搜索*.jpg会返回诸如*.jpg、*.jpg2、*.jpegfileformat等文件。
这种奇怪的行为(认为不太优雅)是为了支持8.3文件名格式。正如某博客所述:“一个名为“alongfilename.longextension”的文件有一个等效的8.3文件名“along~1.lon”。如果过滤扩展名“.lon”,那么上述8.3文件名将是一个匹配项。”这就是GetFiles()方法这样表现的原因。
MSDN官方解释如下:当使用星号通配符字符在searchPattern中(例如"*.txt"),匹配行为取决于指定的文件扩展名的长度。一个具有恰好三个字符的文件扩展名的searchPattern将返回具有三个或更多字符的扩展名的文件,其中前三个字符与searchPattern中指定的文件扩展名匹配。一个具有一个、两个或超过三个字符的文件扩展名的searchPattern只返回具有恰好那个长度的扩展名的文件,并且与searchPattern中指定的文件扩展名匹配。当使用问号通配符字符时,此方法只返回与指定文件扩展名匹配的文件。例如,给定两个文件在目录中,“file1.txt”和“file1.txtother”,一个搜索模式为"file?.txt"只返回第一个文件,而一个搜索模式为"file*.txt"返回两个文件。
在情况下,遇到了一个bug,因为临时将一个XML文件重命名为xxx.XML2222,以便将其从应用程序中移除。程序仍然在读取它,导致它的行为不正确。
如果想防止这种行为,需要手动检查返回的FileInfo类数组,以移除那些不匹配模式的文件。一个优雅的方法是编写一个MethodInfo扩展到DirectoryInfo类,如下所示:
public static FileInfo[] GetFilesByExactMatchExtension(this DirectoryInfo dinfo, string pSearchWildcard)
{
FileInfo[] files = dinfo.GetFiles(pSearchWildcard);
if (files.Length == 0)
return files;
string extensionSearch = Path.GetExtension(pSearchWildcard).ToLowerInvariant();
List filtered = new List();
foreach (FileInfo finfo in files)
{
if (finfo.Extension.ToLowerInvariant() != extensionSearch)
continue;
filtered.Add(finfo);
}
return filtered.ToArray();
}
通过这种方式,只需使用DirectoryInfo类的常规GetFiles()方法,现在将找到全新的GetFilesByExactMatchExtension(),它将具有所需的行为。