2012-08-30 138 views
3

我想在C#中使用各種文件功能,如File.GetLastWriteTime,複製命令放置在路徑大於最大允許的路徑在Windows 7 ie 260上的文件。它給我一個錯誤長路徑名稱。在MSDN支持上,他們要求在路徑前使用\\?\。我做了同樣的事情,但我仍然得到了同樣的錯誤,似乎沒有任何改變。以下是我的代碼。請讓我知道如果我使用它正確的或我需要添加任何東西:
這些所有的lib我使用的代碼是有其他的事情也:錯誤:文件路徑太長

下面是各個代碼:

filesToBeCopied = Directory.GetFiles(path,"*",SearchOption.AllDirectories); 
for (int j = 0; j < filesToBeCopied.Length; j++) 
{ 
    try 
    { 
     String filepath = @"\\?\" + filesToBeCopied[j]; 
     File.GetLastWriteTime(filepath); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Error Inside the single file iteration for the path:" + 
      filesToBeCopied[j] + " . The exception is :" + ex.Message); 
    } 
} 

其中as path是在Windows機器上以驅動器號開頭的文件夾的路徑。爲前:d:\abc\bcd\cd\cdc\dc\..........

+1

是什麼路徑看起來像是造成錯誤?你能把它粘貼在這裏嗎? –

+0

以下是路徑:'D:\ abcdefghi_abc \ abcdefghis abcd abcdef company1 \ abcdefghis abcd abcdef company \ project abcde \ Do Not Delete - EP120605003 \ 002圖像準備\法國興業銀行(開放式接入) - 返回2012年5月18日)\ 004 OCR \ 001 Ocr工作\ 003分區文件\ 4F33DBE75836ACFA95BE3B14B7BEFE5E.split' –

+2

.Net不支持長路徑,您必須直接使用P/Invoke調用API或縮短路徑。 http://blogs.msdn.com/b/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx –

回答

1

嘗試使用此代碼

var path = Path.Combine(@"\\?\", filesToBeCopied[j]); //don't forget extension 

「\?\」前綴的路徑字符串告訴的Windows API禁用所有字符串解析,並直接發送它後面的字符串到文件系統。

重要提示:不是所有的文件I/O API的支持 「?\ \」,你應該看看參考主題爲每個API

+0

我只是想鏈接那個重要的筆記... – Killnine

+0

嗨,上面的代碼甚至沒有組合路徑,因爲我在消息框中合併後顯示的路徑,它顯示了我的原始路徑。 –

+0

有沒有人得到這個工作?使用.NET 4.0和Windows 7,我無法使用File,FileInfo,Directory或DirectoryInfo類。 –

-1

http://www.codinghorror.com/blog/2006/11/filesystem-paths-how-long-is-too-long.html

I recently imported some source code for a customer that exceeded the maximum path limit of 256 characters.

您粘貼的路徑爲285個字符。

正如您在您的評論所指出的,在這裏MSDN的鏈接(http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maximum%5Fpath%5Flength)解釋了這個長度更詳細:

In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length for a path is MAX_PATH, which is defined as 260 characters. A local path is structured in the following order: drive letter, colon, backslash, name components separated by backslashes, and a terminating null character. For example, the maximum path on drive D is "D:\some 256-character path string" where "" represents the invisible terminating null character for the current system codepage. (The characters < > are used here for visual clarity and cannot be part of a valid path string.)

關於\\?\功能:

Many but not all file I/O APIs support "\?\"; you should look at the reference topic for each API to be sure.

+0

感謝您的回覆,但你能否告訴我是否有任何簡單的解決方案或解決方法,因爲在這個時候我不能改變應用程序使用pinvoke –

+0

只做了一個基本的SO搜索:http:// stackoverflow.com/questions/1190614/accessing-files-beyond-max-path-in-c-net 所選答案鏈接(http://blogs.msdn.com/b/bclteam/archive/2007/02/ 13/long-paths-in-net-1-of-3-kim-hamilton.aspx)可能會提供一些解決方案,但顯然我不能答應任何事情。 「你的里程可能會有所不同」 – Killnine

2

據我所知,如果路徑太長,則無法直接訪問文件(直接指我使用File的方法,通過構造函數創建FileInfo,或者使用Directory.GetFiles(string fileName)

我發現的唯一方法就是讓你訪問這樣一個文件,就是在路徑變得太長之前訪問路徑中的某個目錄,然後以編程方式向下走,直到你看到你的文件,如所見here

我已經從那裏拿走了我的代碼,並對其進行了一些修改,以便爲具有「太長」路徑的文件返回FileInfo對象。使用此代碼,您可以在返回的FileInfo對象(如LastWriteTime)上訪問必要的屬性但它仍然有一些限制,如無法使用CopyTo()OpenText()等功能。

// Only call GetFileWithLongPath() if the path is too long 
// ... otherwise, new FileInfo() is sufficient 
private static FileInfo GetFile(string path) 
{ 
    if (path.Length >= MAX_FILE_PATH) 
    { 
     return GetFileWithLongPath(path); 
    } 
    else return new FileInfo(path); 
} 

static int MAX_FILE_PATH = 260; 
static int MAX_DIR_PATH = 248; 

private static FileInfo GetFileWithLongPath(string path) 
{ 
    string[] subpaths = path.Split('\\'); 
    StringBuilder sbNewPath = new StringBuilder(subpaths[0]); 
    // Build longest sub-path that is less than MAX_PATH characters 
    for (int i = 1; i < subpaths.Length; i++) 
    { 
     if (sbNewPath.Length + subpaths[i].Length >= MAX_DIR_PATH) 
     { 
      subpaths = subpaths.Skip(i).ToArray(); 
      break; 
     } 
     sbNewPath.Append("\\" + subpaths[i]); 
    } 
    DirectoryInfo dir = new DirectoryInfo(sbNewPath.ToString()); 
    bool foundMatch = dir.Exists; 
    if (foundMatch) 
    { 
     // Make sure that all of the subdirectories in our path exist. 
     // Skip the last entry in subpaths, since it is our filename. 
     // If we try to specify the path in dir.GetDirectories(), 
     // We get a max path length error. 
     int i = 0; 
     while (i < subpaths.Length - 1 && foundMatch) 
     { 
      foundMatch = false; 
      foreach (DirectoryInfo subDir in dir.GetDirectories()) 
      { 
       if (subDir.Name == subpaths[i]) 
       { 
        // Move on to the next subDirectory 
        dir = subDir; 
        foundMatch = true; 
        break; 
       } 
      } 
      i++; 
     } 
     if (foundMatch) 
     { 
      // Now that we've gone through all of the subpaths, see if our file exists. 
      // Once again, If we try to specify the path in dir.GetFiles(), 
      // we get a max path length error. 
      foreach (FileInfo fi in dir.GetFiles()) 
      { 
       if (fi.Name == subpaths[subpaths.Length - 1]) 
       { 
        return fi; 
       } 
      } 
     } 
    } 
    // If we didn't find a match, return null; 
    return null; 
} 

現在你已經看到了,去沖洗眼睛,然後縮短你的路。

+0

感謝jon,但我的問題不僅限於filewritetime,我必須使用所有其他功能,如複製刪除和創建等效目錄作爲其數據備份代碼..... –

5

下面是至少你的請求的複印部的解決方案(謝謝pinvoke.net):

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] 
static extern bool CopyFile(string lpExistingFileName, string lpNewFileName, bool bFailIfExists); 

然後實際拷貝文件:

// Don't forget the '\\?\' for long paths 
string reallyLongPath = @"\\?\d:\abc\bcd\cd\cdc\dc\.........."; 
string destination = @"C:\some\other\path\filename.txt"; 
CopyFile(reallyLongPath , destination, false); 
+0

謝謝。讓我檢查一下。 –