簡體   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