在Visual Studio的即时窗口中:

> Path.Combine(@"C:\x", "y")
"C:\\x\\y"
> Path.Combine(@"C:\x", @"\y")
"\\y"

看来它们应该是一样的。

旧的FileSystemObject.BuildPath()不是这样工作的……


当前回答

由于不知道实际的细节,我猜测它尝试像连接相对uri那样连接。例如:

urljoin('/some/abs/path', '../other') = '/some/abs/other'

这意味着当您使用前面的斜杠连接路径时,实际上是将一个基底连接到另一个基底,在这种情况下,第二个基底优先。

其他回答

这实际上是有意义的,在某种程度上,考虑到(相对)路径通常是如何处理的:

string GetFullPath(string path)
{
     string baseDir = @"C:\Users\Foo.Bar";
     return Path.Combine(baseDir, path);
}

// Get full path for RELATIVE file path
GetFullPath("file.txt"); // = C:\Users\Foo.Bar\file.txt

// Get full path for ROOTED file path
GetFullPath(@"C:\Temp\file.txt"); // = C:\Temp\file.txt

真正的问题是:为什么以“\”开头的路径被认为是“根路径”?这对我来说也很新鲜,但它在Windows上是这样工作的:

new FileInfo("\windows"); // FullName = C:\Windows, Exists = True
new FileInfo("windows"); // FullName = C:\Users\Foo.Bar\Windows, Exists = False

删除Path.Combine的第二个参数(path2)中的起始斜杠('\')。

这个\表示“当前驱动器的根目录”。在你的例子中,它指的是当前驱动器根目录中的“test”文件夹。所以,这可以等于"c:\test"。

由于不知道实际的细节,我猜测它尝试像连接相对uri那样连接。例如:

urljoin('/some/abs/path', '../other') = '/some/abs/other'

这意味着当您使用前面的斜杠连接路径时,实际上是将一个基底连接到另一个基底,在这种情况下,第二个基底优先。

我想解决这个问题:

string sample1 = "configuration/config.xml";
string sample2 = "/configuration/config.xml";
string sample3 = "\\configuration/config.xml";

string dir1 = "c:\\temp";
string dir2 = "c:\\temp\\";
string dir3 = "c:\\temp/";

string path1 = PathCombine(dir1, sample1);
string path2 = PathCombine(dir1, sample2);
string path3 = PathCombine(dir1, sample3);

string path4 = PathCombine(dir2, sample1);
string path5 = PathCombine(dir2, sample2);
string path6 = PathCombine(dir2, sample3);

string path7 = PathCombine(dir3, sample1);
string path8 = PathCombine(dir3, sample2);
string path9 = PathCombine(dir3, sample3);

当然,所有路径1-9最后都应该包含一个等效的字符串。这是我想出的PathCombine方法:

private string PathCombine(string path1, string path2)
{
    if (Path.IsPathRooted(path2))
    {
        path2 = path2.TrimStart(Path.DirectorySeparatorChar);
        path2 = path2.TrimStart(Path.AltDirectorySeparatorChar);
    }

    return Path.Combine(path1, path2);
}

我还认为这是相当恼人的字符串处理必须手动完成,我对这背后的原因很感兴趣。