@ Джо, глупый прав! Кроме того, я должен отметить, что эквивалентная функция прекрасно работает в Node.JS ... качая головой в Microsoft ...
NH.
2
@zwcloud Для .NET Core / Standard, Path.Combine()в основном для обратной совместимости (с существующим поведением). Было бы лучше использовать Path.Join(): «В отличие от метода Combine, метод Join не пытается рутировать возвращенный путь. (То есть, если path2 является абсолютным путем, метод Join не отбрасывает path1 и возвращает path2 как Combine. метод делает.) "
Stajs
Ответы:
205
Это своего рода философский вопрос (на который, пожалуй, может ответить только Microsoft), поскольку он делает именно то, что говорится в документации.
Я не знаю, в чем причина. Я думаю, что решение состоит в том, чтобы удалить (или обрезать) DirectorySeparatorChar из начала второго пути; возможно, написать свой собственный метод Combine, который делает это, а затем вызывает Path.Combine ().
Глядя на разобранный код (проверь мой пост), ты прав в некотором смысле.
Гульзар Назим
7
Я предполагаю, что это работает таким образом, чтобы обеспечить легкий доступ к алгоритму «текущий рабочий каталог».
БКС,
Кажется, это работает как выполнение последовательности cd (component)из командной строки. Звучит разумно для меня.
Адриан Ратнапала
11
Я использую эту обрезку, чтобы получить желаемый эффект string strFilePath = Path.Combine (basePath, otherPath.TrimStart (new char [] {'\\', '/'}));
Мэтью Лок
3
Я изменить свой рабочий код в Path.Combineтолько , чтобы быть безопасным , но потом он сломался .. Это так глупо :)
SOTN
23
Это дизассемблированный код из .NET Reflector для метода Path.Combine. Проверьте функцию IsPathRooted. Если второй путь является корневым (начинается с DirectorySeparatorChar), верните второй путь как есть.
На мой взгляд, это ошибка. Проблема в том, что существует два разных типа «абсолютных» путей. Путь "d: \ mydir \ myfile.txt" является абсолютным, путь "\ mydir \ myfile.txt" также считается "абсолютным", даже если в нем отсутствует буква диска. На мой взгляд, правильное поведение заключается в добавлении буквы диска из первого пути, когда второй путь начинается с разделителя каталогов (и не является UNC-путем). Я бы порекомендовал написать свою собственную вспомогательную функцию-обертку, которая будет иметь желаемое поведение, если вам это нужно.
Это соответствует спецификации, но это не то, чего я ожидал.
dthrasher 26.09.09
@ Джейк Это не избежать ошибки; несколько человек долго и усердно думают о том, как что-то сделать, а затем придерживаются того, с чем они согласны. Также обратите внимание на разницу между .Net framework (библиотекой, которая содержит Path.Combine) и языком C #.
Если один из указанных путей является строкой нулевой длины, этот метод возвращает другой путь. Если path2 содержит абсолютный путь, этот метод возвращает path2.
Некоторые советуют, что пространства имен должны сталкиваться, ... я пошел Pathy, как небольшой, и чтобы избежать столкновения пространства имен System.IO.Path.
Это означает, что когда вы соединяете путь с предыдущей косой чертой, вы фактически соединяете одну базу с другой, и в этом случае вторая получает приоритет.
Это на самом деле имеет смысл, в некотором смысле, учитывая, как обычно обрабатываются (относительные) пути:
stringGetFullPath(string path){string baseDir =@"C:\Users\Foo.Bar";returnPath.Combine(baseDir, path);}// Get full path for RELATIVE file pathGetFullPath("file.txt");// = C:\Users\Foo.Bar\file.txt// Get full path for ROOTED file pathGetFullPath(@"C:\Temp\file.txt");// = C:\Temp\file.txt
Реальный вопрос: почему пути, которые начинаются с "\", считаются «укорененными»? Для меня это тоже было новым, но в Windows это работает так :
Это \ означает «корневой каталог текущего диска». В вашем примере это означает «тестовую» папку в корневом каталоге текущего диска. Таким образом, это может быть равно «c: \ test».
Как упоминал Райан, он делает именно то, что написано в документации.
От времени DOS, текущий диск и текущий путь различаются.
\это корневой путь, но для ТЕКУЩЕГО ДИСКА.
Для каждого « диска » существует отдельный « текущий путь ». Если вы меняете диск с помощью, cd D:вы не изменяете текущий путь на D:\, а на: «D: \ независимо от того, что было \ the \ last \ path \ accessed \ on \ this \ disk» ...
Таким образом, в Windows буквальное значение @"\x"означает: «CURRENTDISK: \ x». Следовательно Path.Combine(@"C:\x", @"\y"), вторым параметром является корневой путь, а не относительный, хотя и не на известном диске ... И поскольку неизвестно, каким может быть «текущий диск», возвращается python "\\y".
Path.Combine()
в основном для обратной совместимости (с существующим поведением). Было бы лучше использоватьPath.Join()
: «В отличие от метода Combine, метод Join не пытается рутировать возвращенный путь. (То есть, если path2 является абсолютным путем, метод Join не отбрасывает path1 и возвращает path2 как Combine. метод делает.) "Ответы:
Это своего рода философский вопрос (на который, пожалуй, может ответить только Microsoft), поскольку он делает именно то, что говорится в документации.
System.IO.Path.Combine
«Если path2 содержит абсолютный путь, этот метод возвращает path2.»
Вот фактический метод Combine из источника .NET. Вы можете видеть, что он вызывает CombineNoChecks , который затем вызывает IsPathRooted на path2 и возвращает этот путь, если так:
Я не знаю, в чем причина. Я думаю, что решение состоит в том, чтобы удалить (или обрезать) DirectorySeparatorChar из начала второго пути; возможно, написать свой собственный метод Combine, который делает это, а затем вызывает Path.Combine ().
источник
cd (component)
из командной строки. Звучит разумно для меня.Path.Combine
только , чтобы быть безопасным , но потом он сломался .. Это так глупо :)Это дизассемблированный код из .NET Reflector для метода Path.Combine. Проверьте функцию IsPathRooted. Если второй путь является корневым (начинается с DirectorySeparatorChar), верните второй путь как есть.
источник
Я хотел решить эту проблему:
Конечно, все пути 1-9 должны содержать эквивалентную строку в конце. Вот метод PathCombine, который я придумал:
Я также думаю, что довольно досадно, что эту обработку строк нужно выполнять вручную, и мне было бы интересно узнать причину этого.
источник
На мой взгляд, это ошибка. Проблема в том, что существует два разных типа «абсолютных» путей. Путь "d: \ mydir \ myfile.txt" является абсолютным, путь "\ mydir \ myfile.txt" также считается "абсолютным", даже если в нем отсутствует буква диска. На мой взгляд, правильное поведение заключается в добавлении буквы диска из первого пути, когда второй путь начинается с разделителя каталогов (и не является UNC-путем). Я бы порекомендовал написать свою собственную вспомогательную функцию-обертку, которая будет иметь желаемое поведение, если вам это нужно.
источник
Path.Combine
) и языком C #.Из MSDN :
В вашем примере path2 является абсолютным.
источник
Следуя совету Кристиана Грауса в его блоге «Вещи, который я ненавижу в Microsoft» под названием « Path.Combine по сути бесполезен». , Вот мое решение:
Некоторые советуют, что пространства имен должны сталкиваться, ... я пошел
Pathy
, как небольшой, и чтобы избежать столкновения пространства именSystem.IO.Path
.Редактировать : Добавлены проверки нулевых параметров
источник
Этот код должен сделать свое дело:
источник
Не зная реальных деталей, я предполагаю, что он пытается присоединиться так, как если бы вы могли присоединиться к относительным URI. Например:
Это означает, что когда вы соединяете путь с предыдущей косой чертой, вы фактически соединяете одну базу с другой, и в этом случае вторая получает приоритет.
источник
Причина:
Ваш второй URL считается абсолютным путем.
Combine
Метод будет возвращать последний путь, только если последний путь является абсолютным путем.Решение: Просто удалите начальную косую черту
/
вашего второго Пути (/SecondPath
кSecondPath
). Тогда это работает, как вы исключили.источник
Это на самом деле имеет смысл, в некотором смысле, учитывая, как обычно обрабатываются (относительные) пути:
Реальный вопрос: почему пути, которые начинаются с
"\"
, считаются «укорененными»? Для меня это тоже было новым, но в Windows это работает так :источник
Если вы хотите объединить оба пути без потери пути, вы можете использовать это:
Или с переменными:
В обоих случаях возвращается «C: \ test \ test».
Сначала я оцениваю, начинается ли Path2 с /, и если оно истинно, возвращаю Path2 без первого символа. В противном случае верните полный путь2.
источник
== @"\"
чекPath.IsRooted()
вызовом, поскольку"\"
это не единственный символ, который нужно учитывать.Эти два метода должны уберечь вас от случайного объединения двух строк, в каждой из которых есть разделитель.
источник
Это \ означает «корневой каталог текущего диска». В вашем примере это означает «тестовую» папку в корневом каталоге текущего диска. Таким образом, это может быть равно «c: \ test».
источник
Удалите начальную косую черту ('\') во втором параметре (path2) файла Path.Combine.
источник
Я использовал агрегатную функцию для объединения путей, как показано ниже:
источник
Как упоминал Райан, он делает именно то, что написано в документации.
От времени DOS, текущий диск и текущий путь различаются.
\
это корневой путь, но для ТЕКУЩЕГО ДИСКА.Для каждого « диска » существует отдельный « текущий путь ». Если вы меняете диск с помощью,
cd D:
вы не изменяете текущий путь наD:\
, а на: «D: \ независимо от того, что было \ the \ last \ path \ accessed \ on \ this \ disk» ...Таким образом, в Windows буквальное значение
@"\x"
означает: «CURRENTDISK: \ x». СледовательноPath.Combine(@"C:\x", @"\y")
, вторым параметром является корневой путь, а не относительный, хотя и не на известном диске ... И поскольку неизвестно, каким может быть «текущий диск», возвращается python"\\y"
.источник