C#获取绝对路径
Getting absolute path in C#
我知道这个问题已经回答了很多次,我的解决方案几乎在所有情况下都有效,除了一个。
有问题的代码是这样的:
Path.GetFullPath(Path.Combine(rootFolder, relativeFilePath))
即使相对路径、UNC 和绝对路径杂乱无章,它在大多数情况下也能正常工作,如下所示:
// These results are OK
Path.GetFullPath(Path.Combine(@"a:\b\c", @"e.txt")); // Returns: "a:\b\c\e.txt"
Path.GetFullPath(Path.Combine(@"a:\b\c", @"..\e.txt")); // Returns: "a:\b\e.txt"
Path.GetFullPath(Path.Combine(@"a:\b\c", @"d:\e.txt")); // Returns: "d:\e.txt"
但是在这种情况下它没有按预期工作:
Path.GetFullPath(Path.Combine(@"a:\b\c", @"\e.txt"))
预期结果是 "a:\e.txt",但代码是 returns "c:\e.txt"。 "c:" 是当前驱动器,因此它解决了难题的一部分,但为什么会发生这种情况?是否有另一种方法来获取适用于所有情况的完整路径?
编辑: 根据答案中的信息,这里是有效的解决方案。虽然可能需要一些空检查和替代目录分隔符字符检查:
var rootDir = @"a:\b\c";
var filePath = @"\e.txt";
var result = (Path.IsPathRooted(filePath) &&
Path.GetPathRoot(filePath) == Path.DirectorySeparatorChar.ToString()) ?
Path.GetFullPath(Path.Combine(Path.GetPathRoot(rootDir), filePath.Substring(1))) :
Path.GetFullPath(Path.Combine(rootDir, filePath));
如documentation中所写:
If path2 includes a root, path2 is returned.
path2
以斜杠开头的事实使其成为根。
此外,在 Path.GetFullPath 中:
This method uses current directory and current volume information to fully qualify path. If you specify a file name only in path, GetFullPath returns the fully qualified path of the current directory.
根据文档:
If path2 includes a root, path2 is returned.
查看 reference source 我们可以看到,如果路径以“\”开头,则认为它包含根。
// Tests if the given path contains a root. A path is considered rooted
// if it starts with a backslash ("\") or a drive letter and a colon (":").
//
[Pure]
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;
}
我知道这个问题已经回答了很多次,我的解决方案几乎在所有情况下都有效,除了一个。
有问题的代码是这样的:
Path.GetFullPath(Path.Combine(rootFolder, relativeFilePath))
即使相对路径、UNC 和绝对路径杂乱无章,它在大多数情况下也能正常工作,如下所示:
// These results are OK
Path.GetFullPath(Path.Combine(@"a:\b\c", @"e.txt")); // Returns: "a:\b\c\e.txt"
Path.GetFullPath(Path.Combine(@"a:\b\c", @"..\e.txt")); // Returns: "a:\b\e.txt"
Path.GetFullPath(Path.Combine(@"a:\b\c", @"d:\e.txt")); // Returns: "d:\e.txt"
但是在这种情况下它没有按预期工作:
Path.GetFullPath(Path.Combine(@"a:\b\c", @"\e.txt"))
预期结果是 "a:\e.txt",但代码是 returns "c:\e.txt"。 "c:" 是当前驱动器,因此它解决了难题的一部分,但为什么会发生这种情况?是否有另一种方法来获取适用于所有情况的完整路径?
编辑: 根据答案中的信息,这里是有效的解决方案。虽然可能需要一些空检查和替代目录分隔符字符检查:
var rootDir = @"a:\b\c";
var filePath = @"\e.txt";
var result = (Path.IsPathRooted(filePath) &&
Path.GetPathRoot(filePath) == Path.DirectorySeparatorChar.ToString()) ?
Path.GetFullPath(Path.Combine(Path.GetPathRoot(rootDir), filePath.Substring(1))) :
Path.GetFullPath(Path.Combine(rootDir, filePath));
如documentation中所写:
If path2 includes a root, path2 is returned.
path2
以斜杠开头的事实使其成为根。
此外,在 Path.GetFullPath 中:
This method uses current directory and current volume information to fully qualify path. If you specify a file name only in path, GetFullPath returns the fully qualified path of the current directory.
根据文档:
If path2 includes a root, path2 is returned.
查看 reference source 我们可以看到,如果路径以“\”开头,则认为它包含根。
// Tests if the given path contains a root. A path is considered rooted
// if it starts with a backslash ("\") or a drive letter and a colon (":").
//
[Pure]
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;
}