Search code examples
c#.netcase-insensitive

Open a file while ignoring case in the path and filename


I can convert pathAndFilename to lower case, but its like I need a way to tell OpenRead to be case-insenstiive.

// pathAndFileName has been converted with .ToLower()
using (FileStream fileStream = File.OpenRead(pathAndFileName))
{
    Bitmap bitmap = new Bitmap(fileStream);
    Image image = (Image)bitmap;
}

Solution

  • If you try to access files on a machine running Linux or some other operating system where file names are case sensitive, a workaround could be (not tested!) to use the filename you have as a pattern to list the files in the directory. Be aware that there can be multiple files with the same name and just different spelling variants. This helper function will raise an exception in this case.

    static void Main(string[] args)
    {
        string pathAndFileName = ..your file name...;
        string resultFileName = GetActualCaseForFileName(pathAndFileName);
    
        using (FileStream fileStream = File.OpenRead(resultFileName))
        {
            Bitmap bitmap = new Bitmap(fileStream);
            Image image = (Image)bitmap;
        }    
    
    
        Console.WriteLine(resultFileName);
    }
    
    private static string GetActualCaseForFileName(string pathAndFileName)
    {
        string directory = Path.GetDirectoryName(pathAndFileName);
        string pattern = Path.GetFileName(pathAndFileName);
        string resultFileName;
    
        // Enumerate all files in the directory, using the file name as a pattern
        // This will list all case variants of the filename even on file systems that
        // are case sensitive
        IEnumerable<string> foundFiles = Directory.EnumerateFiles(directory, pattern);
    
        if (foundFiles.Any())
        {
            if (foundFiles.Count() > 1)
            {
                // More than two files with the same name but different case spelling found
                throw new Exception("Ambiguous File reference for " + pathAndFileName);
            }
            else
            {
                resultFileName = foundFiles.First();
            }
        }
        else
        {
            throw new FileNotFoundException("File not found" + pathAndFileName, pathAndFileName);
        }
    
        return resultFileName;
    }