C#文件路径Recasing
-
20-08-2019 - |
题
我试图写一个静态成员函数在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路径进行测试。