2009-01-26 60 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路徑。