从Visual Studio 的立即窗口中:
> Path.Combine(@"C:\x", "y")
"C:\\x\\y"
> Path.Combine(@"C:\x", @"\y")
"\\y"
似乎它们应该是相同的。
旧的FileSystemObject.BuildPath()无法以这种方式工作...
Path.Combine()
主要是为了向后兼容(与现有行为)。您最好使用Path.Join()
以下方法
从Visual Studio 的立即窗口中:
> Path.Combine(@"C:\x", "y")
"C:\\x\\y"
> Path.Combine(@"C:\x", @"\y")
"\\y"
似乎它们应该是相同的。
旧的FileSystemObject.BuildPath()无法以这种方式工作...
Path.Combine()
主要是为了向后兼容(与现有行为)。您最好使用Path.Join()
以下方法
Answers:
这是一个哲学问题(也许只有Microsoft才能真正回答),因为它确实在按照文档中的说明进行操作。
“如果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;
}
我不知道这是什么理由。我猜解决方案是从第二个路径的开头剥离(或修剪)DirectorySeparatorChar;也许编写自己的Combine方法来执行该操作,然后调用Path.Combine()。
cd (component)
从命令行执行一系列操作一样。对我来说听起来很合理。
Path.Combine
只是为了安全起见,但是随后它
这是.NET Reflector中用于Path.Combine方法的反汇编代码。检查IsPathRooted函数。如果第二条路径是根目录(以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;
}
我想解决这个问题:
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);
}
我还认为必须手动完成此字符串处理是很烦人的,并且我会对这背后的原因感兴趣。
我认为这是一个错误。问题是存在两种不同类型的“绝对”路径。路径“ d:\ mydir \ myfile.txt”是绝对路径,路径“ \ mydir \ myfile.txt”也被视为“绝对路径”,即使它缺少驱动器号。我认为正确的行为是,当第二个路径以目录分隔符开头(而不是UNC路径)时,在第一个路径前添加驱动器号。我建议编写自己的辅助包装函数,如果需要的话,该函数具有所需的行为。
Path.Combine
)与C#语言之间的区别。
在克里斯蒂安·格劳斯(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);
}
}
有人建议命名空间应该发生冲突,...我Pathy
略微同意,以避免与冲突System.IO.Path
。
编辑:添加了空参数检查
原因:
您的第二个URL被认为是绝对路径,Combine
如果最后一个路径是绝对路径,则该方法只会返回最后一个路径。
解决方案:只需删除/
第二个路径(/SecondPath
到SecondPath
)的开始斜杠。然后按您的要求工作。
考虑到通常如何处理(相对)路径,这实际上在某种意义上是有意义的:
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(@"C:\test", @"\test".Substring(0, 1) == @"\" ? @"\test".Substring(1, @"\test".Length - 1) : @"\test");
或带有变量:
string Path1 = @"C:\Test";
string Path2 = @"\test";
string FullPath = Path.Combine(Path1, Path2.IsRooted() ? Path2.Substring(1, Path2.Length - 1) : Path2);
两种情况都返回“ C:\ test \ test”。
首先,我评估Path2是否以/开头,如果为true,则返回不带第一个字符的Path2。否则,返回完整的Path2。
== @"\"
用Path.IsRooted()
电话代替支票可能更安全,因为"\"
它不是唯一要考虑的字符。
这两种方法可以避免意外连接两个都包含定界符的字符串。
public static string Combine(string x, string y, char delimiter) {
return $"{ x.TrimEnd(delimiter) }{ delimiter }{ y.TrimStart(delimiter) }";
}
public static string Combine(string[] xs, char delimiter) {
if (xs.Length < 1) return string.Empty;
if (xs.Length == 1) return xs[0];
var x = Combine(xs[0], xs[1], delimiter);
if (xs.Length == 2) return x;
var ys = new List<string>();
ys.Add(x);
ys.AddRange(xs.Skip(2).ToList());
return Combine(ys.ToArray(), delimiter);
}
正如Ryan所提到的,它完全按照文档中的说明进行操作。
根据DOS时间,可以区分当前磁盘和当前路径。
\
是根路径,但用于CURRENT DISK。
对于每个“ 磁盘 ”,都有一个单独的“ 当前路径 ”。如果使用来更改磁盘cd D:
,则不要将当前路径更改为D:\
,而是更改为:“ D:\ whatever \ was \ the \ last \ path \ accessed \ on \ this \ disk” ...
因此,在Windows中,文字的@"\x"
含义是:“ CURRENTDISK:\ x”。因此Path.Combine(@"C:\x", @"\y")
,它的第二个参数是一个根路径,而不是一个相对路径,尽管不在一个已知的磁盘中……而且由于不知道可能是“当前磁盘”,因此python返回"\\y"
。
>cd C:
>cd \mydironC\apath
>cd D:
>cd \mydironD\bpath
>cd C:
>cd
>C:\mydironC\apath