2009-01-26 62 views
21

我想在C#中编写静态成员函数,或者在.NET Framework中找到一个将重新指定文件系统指定文件路径的文件路径。C#文件路径回收

例子:

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; 
} 
+0

由于ClearCase。我已经在这个问题上说过了。 – 2009-01-28 05:10:05

回答

21

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

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

没有与此错误,但:相对路径转换为绝对路径。你上面的原始代码也是一样的,所以我假设你确实需要这种行为。

+0

不幸的是,这违反了UNC路径。我需要它在UNC路径上工作。像\\ SERVERNAME \ Hostdir \ MyDocument.docx – 2009-02-06 14:35:35

1

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

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

这是你在找什么?

+0

只有文件存在时,情况才会存在。否则无所谓你不觉得? – manojlds 2011-08-25 22:10:45

+0

这修复了该文件的情况,但整个路径的其余部分仍然不正确。 – PolyTekPatrick 2015-08-01 20:18:30

1

我有更有效率的东西,但是:

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

下面的工作很好,我测试的程度...只有catch是所使用的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); 
1

通过上述@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(); 
} 
0

您会希望系统为您找到该文件。

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

所以我们在目录中搜索,筛选确切的文件名和限制搜索到当前目录:我假装我不知道确切的路径,即对系统搜索做到这一点只有(没有递归)。

这将返回一个字符串数组,包含具有正确套管(如果该文件存在)的单个文件路径,或者不包含任何文件(如果该文件不存在)。

一个警告:您可能需要禁止输入路径中的通配符,因为此方法接受它们并可能找到多个文件。

编辑

盘符似乎依然遵循我们提供的外壳。此外,还需要测试UNC路径。