我试图写一个静态成员函数在C#或找到一个在.NET Framework将重新情况下的文件路径什么文件系统指定。

示例:

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

我试过下面的下面的代码和它的许多变种,它仍然无法正常工作。 我知道视窗是不区分大小写的一般但我需要这些文件路径传递给ClearCase的它参考文件路径套管因为它是一个Unix和Windows应用程序。

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;
}
有帮助吗?

解决方案

这是一个非常简单的实现,假定文件和目录的所有存在并且是可访问的:

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

有与此一错误,但:相对路径被转换为绝对路径。上述原密码也一样,所以我假设你希望这种行为。

其他提示

在以下工作正常到我测试的程度...唯一的缺点是,所用的API仅在Vista是可用的。

static void Main(string[] args)
{
    using (FileStream fs = File.OpenRead(@"D:\temp\case\mytest.txt"))
    {
        StringBuilder path = new StringBuilder(512);
        GetFinalPathNameByHandle(fs.SafeFileHandle.DangerousGetHandle(), path, path.Capacity, 0);
        Console.WriteLine(path.ToString());
    }
}

[DllImport("kernel32.dll", SetLastError = true)]
static extern int GetFinalPathNameByHandle(IntPtr handle, [In, Out] StringBuilder path, int bufLen, int flags);

您可以搜索你想要得到的情况,并返回搜索结果的文件(你要检查存在的文件的外壳,对吧?)。是这样的:

public static string GetProperFilePathCapitalization(string filepath) {
   string directoryPath = Path.GetDirectoryName(filepath);
   string[] files = Directory.GetFiles(directoryPath, Path.GetFileName(filepath));
   return files[0];
}

这是你要找的是什么?

我有一些更有效,但:

1),它似乎并不为所有情况。 (我没有想出哪些文件和目录的它正确地得到外壳哪些它没有图案,和。)

2)它是Windows特定

static string GetProperFilePathCapitalization1(string filename)
{
    StringBuilder sb = new StringBuilder(260);
    int length = GetLongPathName(filename, sb, sb.Capacity);

    if (length > sb.Capacity)
    {
        sb.Capacity = length;
        length = GetLongPathName(filename, sb, sb.Capacity);
    }

    if (0 == length)
        throw new Win32Exception("GetLongPathName");

    return sb.ToString();
}

[DllImport("kernel32.dll")]
static extern int GetLongPathName(string path, StringBuilder pszPath, int cchPath);

通过上述@Ants答案应该的绝对的获得信贷作为公认的答案。不过,我重构了一点我的目的。该方法被打包为扩展方法用于和的FileInfo DirectoryInfo的,并返回修正的以及。

public static DirectoryInfo GetProperCasedDirectoryInfo(this DirectoryInfo dirInfo)
{
    // Inspired by http://stackoverflow.com/a/479198/244342

    if (!dirInfo.Exists)
    {
        // Will not be able to match filesystem
        return dirInfo;
    }

    DirectoryInfo parentDirInfo = dirInfo.Parent;
    if (parentDirInfo == null)
    {
        return dirInfo;
    }
    else
    {
        return parentDirInfo.GetProperCasedDirectoryInfo().GetDirectories(dirInfo.Name)[0];
    }
}

public static FileInfo GetProperCasedFileInfo(this FileInfo fileInfo)
{
    // Inspired by http://stackoverflow.com/a/479198/244342

    if (!fileInfo.Exists)
    {
        // Will not be able to match filesystem
        return fileInfo;
    }

    return fileInfo.Directory.GetProperCasedDirectoryInfo().GetFiles(fileInfo.Name)[0];
}

我一直在敲打我的脑袋上有一定的FileInfo大小写不一致的问题。为了保证稳健性,我做了路径的比较或存储时转换为全部大写。澄清代码的意图,我也有这些扩展方法:

public static string GetPathForKey(this FileInfo File)
{
    return File.FullName.ToUpperInvariant();
}

public static string GetDirectoryForKey(this FileInfo File)
{
    return File.DirectoryName.ToUpperInvariant();
}

您会希望系统为您找到该文件。我假装我不知道确切的路径,即对系统做的搜索的:

var fileName = Path.GetFileName(filePath);
var dir = Path.GetDirectoryName(filePath);
var filePaths = Directory.GetFiles(dir, fileName, SearchOption.TopDirectoryOnly);
var caseCorrectedFilePath = filePaths.FirstOrDefault();

因此,我们在目录中搜索,过滤确切的文件名和限定搜索到当前目录只(没有递归)。

此返回包含或者与正确壳体的单个文件路径(如果该文件存在)的字符串数组或没有(如果该文件不存在)。

一个警告:您可能需要禁止通配符输入路径,因为这种方式接受他们,并可以找到多个文件,因此

修改

的驱动器盘符似乎仍然遵循我们提供的套管。此外,这需要对UNC路径进行测试。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top