从Visual Studio中的立即窗口:
> Path.Combine(@"C:\x", "y")
"C:\\x\\y"
> Path.Combine(@"C:\x", @"\y")
"\\y"
Run Code Online (Sandbox Code Playgroud)
它们似乎都应该是一样的.
旧的FileSystemObject.BuildPath()没有以这种方式工作......
Rya*_*ndy 193
这是一个哲学问题(可能只有微软可以真正回答),因为它正在完成文档所说的内容.
"如果path2包含绝对路径,则此方法返回path2."
这是 .NET源代码中的实际Combine方法.您可以看到它调用CombineNoChecks,然后在path2上调用IsPathRooted并返回该路径,如果是这样的话:
public static String Combine(String path1, String path2) {
if (path1==null || path2==null)
throw new ArgumentNullException((path1==null) ? "path1" : "path2");
Contract.EndContractBlock();
CheckInvalidPathChars(path1);
CheckInvalidPathChars(path2);
return CombineNoChecks(path1, path2);
}
internal static string CombineNoChecks(string path1, string path2)
{
if (path2.Length == 0)
return path1;
if (path1.Length == 0)
return path2;
if (IsPathRooted(path2))
return path2;
char ch = path1[path1.Length - 1];
if (ch != DirectorySeparatorChar && ch != AltDirectorySeparatorChar &&
ch != VolumeSeparatorChar)
return path1 + DirectorySeparatorCharAsString + path2;
return path1 + path2;
}
Run Code Online (Sandbox Code Playgroud)
我不知道原理是什么.我想解决方案是从第二个路径的开头剥离(或修剪)DirectorySeparatorChar; 也许编写自己的Combine方法,然后调用Path.Combine().
Gul*_*zim 23
这是.NET Reflector for Path.Combine方法的反汇编代码.检查IsPathRooted功能.如果第二个路径是root(以DirectorySeparatorChar开头),则按原样返回第二个路径.
public static string Combine(string path1, string path2)
{
if ((path1 == null) || (path2 == null))
{
throw new ArgumentNullException((path1 == null) ? "path1" : "path2");
}
CheckInvalidPathChars(path1);
CheckInvalidPathChars(path2);
if (path2.Length == 0)
{
return path1;
}
if (path1.Length == 0)
{
return path2;
}
if (IsPathRooted(path2))
{
return path2;
}
char ch = path1[path1.Length - 1];
if (((ch != DirectorySeparatorChar) &&
(ch != AltDirectorySeparatorChar)) &&
(ch != VolumeSeparatorChar))
{
return (path1 + DirectorySeparatorChar + path2);
}
return (path1 + path2);
}
public static bool IsPathRooted(string path)
{
if (path != null)
{
CheckInvalidPathChars(path);
int length = path.Length;
if (
(
(length >= 1) &&
(
(path[0] == DirectorySeparatorChar) ||
(path[0] == AltDirectorySeparatorChar)
)
)
||
((length >= 2) &&
(path[1] == VolumeSeparatorChar))
)
{
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
anh*_*ppe 21
我想解决这个问题:
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);
Run Code Online (Sandbox Code Playgroud)
当然,所有路径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);
}
Run Code Online (Sandbox Code Playgroud)
我也认为这个字符串处理必须手动完成是非常烦人的,我对这背后的原因感兴趣.
Wed*_*dge 18
在我看来这是一个错误.问题是有两种不同类型的"绝对"路径.路径"d:\ mydir\myfile.txt"是绝对的,路径"\ mydir\myfile.txt"也被认为是"绝对的",即使它缺少驱动器号.在我看来,正确的行为是当第二条路径以目录分隔符开始时(并且不是UNC路径),从第一条路径前面加上驱动器号.我建议编写自己的帮助程序包装函数,如果需要,它具有您想要的行为.
原因:
您的第二个 URL 被视为绝对路径,并且Combine
如果最后一个路径是绝对路径,则该方法将仅返回最后一个路径。
解决方案:
/
只需从第二个路径(/SecondPath
to )中删除前导斜杠SecondPath
,它就会正常工作。
根据Christian Graus在他的"我讨厌微软的事情"博客中提出的建议,题为" Path.Combine基本没用. ",这是我的解决方案:
public static class Pathy
{
public static string Combine(string path1, string path2)
{
if (path1 == null) return path2
else if (path2 == null) return path1
else return path1.Trim().TrimEnd(System.IO.Path.DirectorySeparatorChar)
+ System.IO.Path.DirectorySeparatorChar
+ path2.Trim().TrimStart(System.IO.Path.DirectorySeparatorChar);
}
public static string Combine(string path1, string path2, string path3)
{
return Combine(Combine(path1, path2), path3);
}
}
Run Code Online (Sandbox Code Playgroud)
有人建议命名空间应该碰撞,...我Pathy
一点一点地去,并避免名称空间冲突System.IO.Path
.
编辑:添加了空参数检查
不知道实际的细节,我的猜测是它尝试加入,就像你可能加入相对的URI.例如:
urljoin('/some/abs/path', '../other') = '/some/abs/other'
Run Code Online (Sandbox Code Playgroud)
这意味着当您使用前面的斜杠加入路径时,实际上是将一个基础连接到另一个基础,在这种情况下,第二个基础优先.
这段代码应该可以解决问题:
string strFinalPath = string.Empty;
string normalizedFirstPath = Path1.TrimEnd(new char[] { '\\' });
string normalizedSecondPath = Path2.TrimStart(new char[] { '\\' });
strFinalPath = Path.Combine(normalizedFirstPath, normalizedSecondPath);
return strFinalPath;
Run Code Online (Sandbox Code Playgroud)