繁体   English   中英

C#结合绝对路径和相对路径,Path.GetFullPath()不一致

[英]C# combining absolute and relative paths, Path.GetFullPath() inconsistent

我注意到当我使用Path.GetFullPath(Path.Combine(@“ c:\\ folder \\”,“ \\ subfolder \\ file.txt”))时,它将返回路径c:\\ subfolder \\ file.txt,而不是预期的组合路径c:\\ folder \\ subfolder \\ file.txt。 这些方法似乎无法处理第二个组合输入上的“ \\”。 有谁遇到过这种情况,并找到了更好的合并路径解决方案?

var test1 = Path.GetFullPath(Path.Combine(@"C:\users\dev\desktop\testfiles\", @".\test1.txt"));
var test2 = Path.GetFullPath(Path.Combine(@"C:\users\dev\desktop\testfiles\", @"\test2.txt"));//
var test3 = Path.GetFullPath(Path.Combine(@"C: \users\dev\desktop\testfiles\", @"test3.txt"));
var test4 = Path.GetFullPath(Path.Combine(@"C:\users\dev\desktop\testfiles\",@".\XXX\test4.txt"));
var test5 = Path.GetFullPath(Path.Combine(@"C:\users\dev\desktop\testfiles\", @"\XXX\test5.txt"));//
var test6 = Path.GetFullPath(Path.Combine(@"C:\users\dev\desktop\testfiles\", @"XXX\test6.txt"));
var test7 = Path.GetFullPath(Path.Combine(@"C:\users\dev\desktop\testfiles\", @"\somefile\that\doesnt\exist.txt"));//

结果是

test1 is "C:\users\dev\desktop\testfiles\test1.txt"
test2 is wrong "\test2.txt"
test3 is "C: \users\dev\desktop\testfiles\test3.txt"
test4 is "C:\users\dev\desktop\testfiles\XXX\test4.txt"
test5 is wrong "c:\XXX\test5.txt"
test6 is "C:\users\dev\desktop\testfiles\XXX\test6.txt"
test7 is wrong "c:\somefile\that\doesnt\exist.txt"

基本上,我正在做的是将源路径与文本文件中的各个文件路径组合在一起,以便可以将这些文件复制到目标位置,并且希望维护子文件夹的层次结构。

例如,文件列表的常见情况是相同的,但是要引用特定的源文件夹版本。

source path + individual file path
\\myserver\project\1.x + \dll\important.dll

应该以相同的方式复制到目的地

c:\myproject\ + \dll\important.dll

因此会有变量; 源,目标,文件[数组或列表]

我当前的前进方式是使用String.TRIM()方法删除特殊字符。 \\ /,然后将路径与Path.Combine,Path.GetFullPath组合在一起。 但是我认为也许有人意识到了类似情况的更好方法。

在目标中创建子文件夹也很麻烦,基本上是使用String.LastIndexOf(@'\\')将文件名与文件夹名分开。 这似乎还有些粗略,但是更好的方法超出了我的经验。

类似的问题: 具有相对路径字符串的Path.Combine绝对


由于有了反馈,我现在知道\\ file.txt被认为是完全限定的(绝对)路径,这就是为什么Combine方法以这种方式起作用的原因。

如果文件名不是以下列之一开头,则它是相对于当前目录的:

A UNC name of any format, which always start with two backslash characters ("\\"). For more information, see the next section.
A disk designator with a backslash, for example "C:\" or "d:\".
A single backslash, for example, "\directory" or "\file.txt". This is also referred to as an absolute path.

https://msdn.microsoft.com/zh-CN/library/windows/desktop/aa365247(v=vs.85).aspx#fully_qualified_vs._relative_paths

基于MSDN文档 ,这是预期的行为。

如果path2不包含根(例如,如果path2不以分隔符或驱动器规范开头),则结果是两个路径的连接,中间插入了分隔符。 如果path2包含根,则返回path2。

在此MSDN文章中讨论了分隔符。

因此,让我们看一下您的测试用例:

var test1 = Path.GetFullPath(Path.Combine(@"C:\users\dev\desktop\testfiles\", @".\test1.txt"));
var test2 = Path.GetFullPath(Path.Combine(@"C:\users\dev\desktop\testfiles\", @"\test2.txt"));

Test1的行为正确,因为它正在使用. 作为有效文件路径的一部分,并将其与第一个参数结合使用以生成组合路径。

由于\\是分隔符,因此Test2的行为符合预期,因此如上所述,它没有第一个参数就被返回。

在.Net框架中没有您要使用的功能-修剪路径或确保相对路径以“。\\”开头为您的实际选项(可能存在于某处的库)。


为什么代码的行为方式不符合您的喜好 (不是“错误”,只是无法满足您的意外期望)。

Combine需要确定左路径的哪一部分将保留,哪些将被替换。 它使用常规文件系统约定来确定(“。”,“ ..”,“ \\”对文件路径具有特殊含义)

以以下内容开头的路径含义:

  • @"\\" or “ /”-从当前设备的根开始-涵盖了大多数您不喜欢的情况
  • @".\\" -表示来自当前目录(因此,在对其进行合并和标准化后,其行为将完全符合您的期望)
  • “ @” .. \\”(可能会多次“向上”)-上一个文件夹-这是您可能不同意的另一种情况。
  • 不是'/'@'\\'任何字符-文件名或当前文件夹的路径

还要注意,以"/"@"\\"以外的其他Path.Combine路径被Path.Combine视为文件路径,当与其他路径组合时,它将丢失最后一段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM