5

我正在尝试使用 C# 中的各种文件函数,例如File.GetLastWriteTime,复制命令放置在大于 Windows 7 上允许的最大路径的路径上的文件,即 260。它给了我一个长路径名错误。在 MSDN 支持上,他们要求\\?\在路径之前使用。我做了同样的事情,但仍然出现同样的错误,似乎没有任何改变。下面是我的代码。请让我知道我是否正确使用它或者我需要添加任何东西:
我正在使用的这些所有库,因为代码还有其他东西:

以下是各自的代码:

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

其中路径是Windows机器上以驱动器号开头的文件夹的路径。例如:d:\abc\bcd\cd\cdc\dc\..........

4

4 回答 4

7

这是至少复制部分请求的解决方案(谢谢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);
于 2012-08-30T20:46:40.783 回答
3

据我所知,如果文件的路径太长,则无法直接访问文件(直接,我的意思是使用 的方法File,通过构造函数创建 aFileInfo或使用Directory.GetFiles(string fileName).

我发现让您访问此类文件的唯一方法是在路径中某处的目录变得太长之前访问它,然后以编程方式沿着树向下走,直到您到达您的文件,如此处所示

我从那里获取了我的代码并对其进行了一些修改,以返回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;
}

既然你已经看到了,那就去冲洗你的眼睛并缩短你的路径。

于 2012-08-30T20:03:29.070 回答
1

尝试使用此代码

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

路径字符串的“\?\”前缀告诉 Windows API 禁用所有字符串解析,并将其后面的字符串直接发送到文件系统。

重要提示:并非所有文件 I/O API 都支持“\?\”,您应该查看每个 API 的参考主题

于 2012-08-30T19:39:33.300 回答
-1

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

我最近为一个超过最大路径限制 256 个字符的客户导入了一些源代码。

您粘贴的路径长度为 285 个字符。

正如您在评论中指出的那样,MSDN 的链接 ( http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maximum%5Fpath%5Flength ) 更详细地解释了这个长度:

在 Windows API(以下段落中讨论的一些例外情况)中,路径的最大长度为 MAX_PATH,定义为 260 个字符。本地路径按以下顺序构造:驱动器号、冒号、反斜杠、由反斜杠分隔的名称组件和终止空字符。例如,驱动器 D 上的最大路径是“D:\some 256-character path string”,其中“”表示当前系统代码页的不可见终止空字符。(字符 < > 在此处用于视觉清晰,不能作为有效路径字符串的一部分。)

关于\\?\功能:

许多但不是所有的文件 I/O API 都支持“\?\”;您应该查看每个 API 的参考主题以确定。

于 2012-08-30T19:46:22.090 回答