[英]C# Filepath Recasing
我正在尝试在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
我已经尝试了下面的代码和它的许多变体,它仍然无法正常工作。 我知道Windows一般不区分大小写但我需要将这些文件路径传递给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);
@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();
}
您可以搜索要获取案例的文件并返回搜索结果(您要检查存在的文件的大小,对吗?)。 像这样的东西:
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);
您将希望系统为您找到该文件。 我这样做是假装我不知道确切的路径,即进行系统搜索 :
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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.