validate not know how exist create check c# file directory case-sensitive file-exists

not - find file c#



Mayúsculas y minúsculas Directory.Exists/File.Exists (5)

Dado que Directory.Exists usa FindFirstFile que no distingue entre mayúsculas y minúsculas, no. Pero puede invocar FindFirstFileEx con un parámetro adicional de Flags establecido en FIND_FIRST_EX_CASE_SENSITIVE

¿Hay alguna manera de tener un Directory.Exists sensible a mayúsculas y minúsculas / File.Exists desde

Directory.Exists(folderPath)

y

Directory.Exists(folderPath.ToLower())

ambos regresan true ?

La mayoría de las veces no importa, pero estoy usando una macro que parece no funcionar si la ruta no coincide con los casos al 100%.


Pruebe estas 2 opciones más simples que no necesitan usar PInvoke y devolver un Boolean nullable (bool?). No soy un experto en el tema, así que sé si este es el código más eficiente pero funciona para mí.

Simplemente pase en una ruta y si el resultado es nulo (HasValue = false) no se encuentra ninguna coincidencia, si el resultado es falso hay una coincidencia exacta; de lo contrario, si es verdadero, hay una coincidencia con un caso de diferencia.

Los métodos GetFiles, GetDirectories y GetDrives devuelven el caso exacto como guardado en su sistema de archivos para que pueda usar un método de comparación sensible a mayúsculas y minúsculas.

NB: para el caso en que la ruta es una unidad exacta (por ejemplo, @ "C: /"), tengo que utilizar un enfoque ligeramente diferente.

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; } }


Prueba esta función:

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

Actualizar:

Como se indica en los comentarios, esto solo verifica los casos en nombre de archivo, no en la ruta. Esto se debe a que el método GetFullPath no devuelve la ruta original de Windows con casos originales, sino una copia de la ruta del parámetro.

Ex:

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

Todos los métodos que probé funcionan de la misma manera: Fileinfo, DirectoryInfo.

Aquí hay una solución usando un método kernel32.dll:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern int GetLongPathName( string path, StringBuilder longPath, int longPathLength ); /// <summary> /// Return true if file exists. Non case sensitive by default. /// </summary> /// <param name="filename"></param> /// <param name="caseSensitive"></param> /// <returns></returns> 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); }


Basado en la solución de esta pregunta , escribí el código a continuación, que distingue entre mayúsculas y minúsculas para toda la ruta excepto la letra de Windows Drive:

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; }

Copié el código de GetWindowsPhysicalPath(string path) de la pregunta

[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; }

Tenga en cuenta que el único problema que encontré con esta función es que la letra de la unidad parece estar siempre en minúscula. Ejemplo: la ruta física en Windows es: D:/Test/test.txt , la función GetWindowsPhysicalPath(string path) devuelve d:/Test/test.txt


Si la ruta (relativa o absoluta) de su archivo es:

string AssetPath = "...";

Lo siguiente asegura que el archivo existe y tiene la carcasa correcta:

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

¡Disfrutar!