简体   繁体   English

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

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

I notice that when I use Path.GetFullPath(Path.Combine(@"c:\\folder\\","\\subfolder\\file.txt")) it returns a path c:\\subfolder\\file.txt, instead of the expected combined path c:\\folder\\subfolder\\file.txt. 我注意到当我使用Path.GetFullPath(Path.Combine(@“ c:\\ folder \\”,“ \\ subfolder \\ file.txt”))时,它将返回路径c:\\ subfolder \\ file.txt,而不是预期的组合路径c:\\ folder \\ subfolder \\ file.txt。 It seems like having a '\\' on the second combined input isn't handled by these methods. 这些方法似乎无法处理第二个组合输入上的“ \\”。 Has anyone come across this and found a better solution for merging paths? 有谁遇到过这种情况,并找到了更好的合并路径解决方案?

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"));//

Results in 结果是

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"

Basically what I'm doing is combining a source path with individual file paths from a text file so that I can copy these files to a destination, and I want to maintain subfolder hierarchy. 基本上,我正在做的是将源路径与文本文件中的各个文件路径组合在一起,以便可以将这些文件复制到目标位置,并且希望维护子文件夹的层次结构。

eg common scenario of the files list being the same, but wanting to reference a specific source folder version. 例如,文件列表的常见情况是相同的,但是要引用特定的源文件夹版本。

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

which should be copied to a destination in the same manner 应该以相同的方式复制到目的地

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

So there would be variables; 因此会有变量; source, destination, files[array or list] 源,目标,文件[数组或列表]

My current way forward is to use String.TRIM() method to remove special chars . 我当前的前进方式是使用String.TRIM()方法删除特殊字符。 \\ / before combining paths with Path.Combine, Path.GetFullPath. \\ /,然后将路径与Path.Combine,Path.GetFullPath组合在一起。 But I thought maybe someone has realized a better way for a similar scenario. 但是我认为也许有人意识到了类似情况的更好方法。

It's also a pain creating the subfolders in the destination, basically im using String.LastIndexOf(@'\\') to separate the filename from the foldername. 在目标中创建子文件夹也很麻烦,基本上是使用String.LastIndexOf(@'\\')将文件名与文件夹名分开。 Which is also seems a little sketchy, but a better way is beyond my experience. 这似乎还有些粗略,但是更好的方法超出了我的经验。

Similar question: Path.Combine absolute with relative path strings 类似的问题: 具有相对路径字符串的Path.Combine绝对


Thanks to the feedback I now know that \\file.txt is considered a fully qualified (absolute) path, which is why the combine method works that way. 由于有了反馈,我现在知道\\ file.txt被认为是完全限定的(绝对)路径,这就是为什么Combine方法以这种方式起作用的原因。

A file name is relative to the current directory if it does not begin with one of the following: 如果文件名不是以下列之一开头,则它是相对于当前目录的:

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/en-nz/library/windows/desktop/aa365247(v=vs.85).aspx#fully_qualified_vs._relative_paths https://msdn.microsoft.com/zh-CN/library/windows/desktop/aa365247(v=vs.85).aspx#fully_qualified_vs._relative_paths

Based on the MSDN Documentation , this is expected behavior. 基于MSDN文档 ,这是预期的行为。

If path2 does not include a root (for example, if path2 does not start with a separator character or a drive specification), the result is a concatenation of the two paths, with an intervening separator character. 如果path2不包含根(例如,如果path2不以分隔符或驱动器规范开头),则结果是两个路径的连接,中间插入了分隔符。 If path2 includes a root, path2 is returned. 如果path2包含根,则返回path2。

Seperator characters are discussed in this MSDN article . 在此MSDN文章中讨论了分隔符。

So let's take a look at your test cases: 因此,让我们看一下您的测试用例:

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 is behaving correctly because it is taking the . Test1的行为正确,因为它正在使用. as part of a valid file path and using it in combination with the first parameter to generate the combined path. 作为有效文件路径的一部分,并将其与第一个参数结合使用以生成组合路径。

Test2 is behaving as expected because the \\ is a separator character, so as described it is returned without the first parameter. 由于\\是分隔符,因此Test2的行为符合预期,因此如上所述,它没有第一个参数就被返回。

There is no functions that you like to use in .Net framework - trimming path or ensuring that relative path starts with ".\\" your real options (probably library that does it exists somewhere). 在.Net框架中没有您要使用的功能-修剪路径或确保相对路径以“。\\”开头为您的实际选项(可能存在于某处的库)。


Why code does not behave the way you like (not "wrong", just not meeting your unexpected expectations). 为什么代码的行为方式不符合您的喜好 (不是“错误”,只是无法满足您的意外期望)。

Combine need to decide which part of left path will stay and which will be replaced. Combine需要确定左路径的哪一部分将保留,哪些将被替换。 It uses regular file system conventions to decide that (".", "..", "\\" have special meaning for file paths) 它使用常规文件系统约定来确定(“。”,“ ..”,“ \\”对文件路径具有特殊含义)

Meaning of path starting with: 以以下内容开头的路径含义:

  • @"\\" or "/" - starting from the root of current device - this covers most cases that you don't like @"\\" or “ /”-从当前设备的根开始-涵盖了大多数您不喜欢的情况
  • @".\\" - means from current directory (hence after combining and normalizing it will behave exactly as you want) @".\\" -表示来自当前目录(因此,在对其进行合并和标准化后,其行为将完全符合您的期望)
  • `@"..\\" (possible multiple "go up") - go up one folder - this is another case you'll likely disagree with. “ @” .. \\”(可能会多次“向上”)-上一个文件夹-这是您可能不同意的另一种情况。
  • any character that is not '/' or @'\\' - file name or path from current folder 不是'/'@'\\'任何字符-文件名或当前文件夹的路径

Also note that path ending on anything but "/" or @"\\" is treated by Path.Combine as file path and when combined with other path it will lose last segment. 还要注意,以"/"@"\\"以外的其他Path.Combine路径被Path.Combine视为文件路径,当与其他路径组合时,它将丢失最后一段。

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

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