区分大小写的Directory.Exists / File.Exists

有没有办法让案例敏感的Directory.Exists / File.Exists从那以后

 Directory.Exists(folderPath) 

 Directory.Exists(folderPath.ToLower()) 

两者都回归true

大多数时候它并不重要但我使用的宏如果路径与100%的情况不匹配似乎不起作用。

由于Directory.Exists使用不区分大小写的FindFirstFile ,因此没有。 但是你可以通过将AdditionalFlags参数设置为FIND_FIRST_EX_CASE_SENSITIVE来PInvoke FindFirstFileEx

根据这个问题的解决方案,我编写了下面的代码,除了Windows驱动器号之外,它对整个路径区分大小写:

  static void Main(string[] args) { string file1 = @"D:\tESt\Test.txt"; string file2 = @"d:\Test\test.txt"; string file3 = @"d:\test\notexists.txt"; bool exists1 = Case_Sensitive_File_Exists(file1); bool exists2 = Case_Sensitive_File_Exists(file2); bool exists3 = Case_Sensitive_File_Exists(file3); Console.WriteLine("\n\nPress any key..."); Console.ReadKey(); } static bool Case_Sensitive_File_Exists(string filepath) { string physicalPath = GetWindowsPhysicalPath(filepath); if (physicalPath == null) return false; if (filepath != physicalPath) return false; else return true; } 

我从问题中复制了GetWindowsPhysicalPath(string path)的代码

  [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern uint GetLongPathName(string ShortPath, StringBuilder sb, int buffer); [DllImport("kernel32.dll")] static extern uint GetShortPathName(string longpath, StringBuilder sb, int buffer); protected static string GetWindowsPhysicalPath(string path) { StringBuilder builder = new StringBuilder(255); // names with long extension can cause the short name to be actually larger than // the long name. GetShortPathName(path, builder, builder.Capacity); path = builder.ToString(); uint result = GetLongPathName(path, builder, builder.Capacity); if (result > 0 && result < builder.Capacity) { //Success retrieved long file name builder[0] = char.ToLower(builder[0]); return builder.ToString(0, (int)result); } if (result > 0) { //Need more capacity in the buffer //specified in the result variable builder = new StringBuilder((int)result); result = GetLongPathName(path, builder, builder.Capacity); builder[0] = char.ToLower(builder[0]); return builder.ToString(0, (int)result); } return null; } 

注意我发现这个函数的唯一问题是,驱动器号似乎总是小写。 示例:Windows上的物理路径为: D:\Test\test.txtGetWindowsPhysicalPath(string path)函数返回d:\Test\test.txt

试试这个function:

 public static bool FileExistsCaseSensitive(string filename) { string name = Path.GetDirectoryName(filename); return name != null && Array.Exists(Directory.GetFiles(name), s => s == Path.GetFullPath(filename)); } 

更新:

如评论中所述,这仅检查文件名中的案例,而不是路径中的案例。 这是因为GetFullPath方法不会返回原始案例的Windows原始路径,而是返回参数路径的副本。

例如:

 GetFullPath("c:\TEST\file.txt") -> "c:\TEST\file.txt" GetFullPath("c:\test\file.txt") -> "c:\test\file.txt" 

我尝试的所有方法都以相同的方式工作:Fileinfo,DirectoryInfo。

这是使用kernel32.dll方法的解决方案:

  [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern int GetLongPathName( string path, StringBuilder longPath, int longPathLength ); ///  /// Return true if file exists. Non case sensitive by default. ///  ///  ///  ///  public static bool FileExists(string filename, bool caseSensitive = false) { if (!File.Exists(filename)) { return false; } if (!caseSensitive) { return true; } //check case StringBuilder longPath = new StringBuilder(255); GetLongPathName(Path.GetFullPath(filename), longPath, longPath.Capacity); string realPath = Path.GetDirectoryName(longPath.ToString()); return Array.Exists(Directory.GetFiles(realPath), s => s == filename); } 

试试这两个更简单的选项,不需要使用PInvoke并返回一个可以为空的布尔值(bool?)。 我不是专家,所以我知道这是否是最有效的代码,但它对我有用。

只需传入一个路径,如果结果为null(HasValue = false),则找不到匹配项,如果结果为false则存在完全匹配,否则如果为true,则存在与差异大小写匹配的情况。

GetFiles,GetDirectories和GetDrives方法都返回保存在文件系统中的确切大小写,因此您可以使用区分大小写的比较方法。

注意:对于路径是精确驱动器的情况(例如@“C:\”),我必须使用稍微不同的方法。

 using System.IO; class MyFolderFileHelper { public static bool? FileExistsWithDifferentCase(string fileName) { bool? result = null; if (File.Exists(fileName)) { result = false; string directory = Path.GetDirectoryName(fileName); string fileTitle = Path.GetFileName(fileName); string[] files = Directory.GetFiles(directory, fileTitle); if (String.Compare(files[0], fileName, false) != 0) result = true; } return result; } public static bool? DirectoryExistsWithDifferentCase(string directoryName) { bool? result = null; if (Directory.Exists(directoryName)) { result = false; directoryName = directoryName.TrimEnd(Path.DirectorySeparatorChar); int lastPathSeparatorIndex = directoryName.LastIndexOf(Path.DirectorySeparatorChar); if (lastPathSeparatorIndex >= 0) { string baseDirectory = directoryName.Substring(lastPathSeparatorIndex + 1); string parentDirectory = directoryName.Substring(0, lastPathSeparatorIndex); string[] directories = Directory.GetDirectories(parentDirectory, baseDirectory); if (String.Compare(directories[0], directoryName, false) != 0) result = true; } else { //if directory is a drive directoryName += Path.DirectorySeparatorChar.ToString(); DriveInfo[] drives = DriveInfo.GetDrives(); foreach(DriveInfo driveInfo in drives) { if (String.Compare(driveInfo.Name, directoryName, true) == 0) { if (String.Compare(driveInfo.Name, directoryName, false) != 0) result = true; break; } } } } return result; } } 

如果文件的(相对或绝对)路径是:

 string AssetPath = "..."; 

以下内容确保文件存在并具有正确的大小写:

 if(File.Exists(AssetPath) && Path.GetFullPath(AssetPath) == Directory.GetFiles(Path.GetDirectoryName(Path.GetFullPath(AssetPath)), Path.GetFileName(Path.GetFullPath(AssetPath))).Single()) { } 

请享用!