Search code examples
c#.netfilenamescase-sensitivefilepath

C# Filepath Recasing


I'm trying to write a static member function in C# or find one in the .NET Framework that will re-case a file path to what the filesystem specifies.

Example:

string filepath = @"C:\temp.txt";
filepath = FileUtility.RecaseFilepath(filepath);

// filepath = C:\Temp.TXT
// Where the real fully qualified filepath in the NTFS volume is C:\Temp.TXT

I've tried the following code below and many variants of it and it still doesn't work. I know Windows is case-insensitive in general but I need to pass these file paths to ClearCase which considers file path casing since it's a Unix and Windows application.

public static string GetProperFilePathCapitalization(string filepath)
{
    string result = "";

    try
    {
        result = Path.GetFullPath(filepath);
        DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(result));
        FileInfo[] fi = dir.GetFiles(Path.GetFileName(result));
        if (fi.Length > 0)
        {
            result = fi[0].FullName;
        }
    }
    catch (Exception)
    {
        result = filepath;
    }

    return result;
}

Solution

  • This is a pretty simple implementation that assumes that the file and directories all exist and are accessible:

    static string GetProperDirectoryCapitalization(DirectoryInfo dirInfo)
    {
        DirectoryInfo parentDirInfo = dirInfo.Parent;
        if (null == parentDirInfo)
            return dirInfo.Name;
        return Path.Combine(GetProperDirectoryCapitalization(parentDirInfo),
                            parentDirInfo.GetDirectories(dirInfo.Name)[0].Name);
    }
    
    static string GetProperFilePathCapitalization(string filename)
    {
        FileInfo fileInfo = new FileInfo(filename);
        DirectoryInfo dirInfo = fileInfo.Directory;
        return Path.Combine(GetProperDirectoryCapitalization(dirInfo),
                            dirInfo.GetFiles(fileInfo.Name)[0].Name);
    }
    

    There is a bug with this, though: Relative paths are converted to absolute paths. Your original code above did the same, so I'm assuming that you do want this behavior.