#c# #.net-4.0 #filesystems #io
#c# #.net-4.0 #файловые системы #io
Вопрос:
К моему удивлению, этот код не дает ожидаемых результатов:
var basePath = @"\serverBaseFolder";
var relativePath = @"MyRelativeFolder";
var combinedPath = Path.Combine(basePath, relativePath);
Результат MyRelativeFolder
вместо ожидаемого \serverBaseFolderMyRelativeFolder
.
Почему это? Каков наилучший способ объединить относительные пути, в которых может быть или не быть косой черты?
РЕДАКТИРОВАТЬ: Я знаю, что могу просто выполнить манипулирование строками в relativePath, чтобы обнаружить и удалить начальную косую черту. Есть ли более безопасный способ сделать это (я думал, Path.Combine
это должен быть безопасный способ), который будет учитывать обратную косую черту и переднюю?
Комментарии:
1. Это не относительный путь.
2. Я бы понял это, если бы спереди было 2 обратных косых черты, что делало бы путь UNC, но одна косая черта? Серьезно?
3. Да; серьезно.
ab
это абсолютный путь. (хотя это относительно диска)
Ответ №1:
Уберите начальную косую черту relativePath
, и это должно сработать.
Причина, по которой это происходит, заключается в этом пути.Combine интерпретируется relativePath
как корневой (абсолютный) путь, потому что в этом случае он начинается с
. Вы можете проверить, является ли путь относительным или корневым, используя Path.IsRooted()
.
Из документа:
Если один из последующих путей является абсолютным путем, то операция объединения сбрасывается, начиная с этого абсолютного пути, отбрасывая все предыдущие объединенные пути.
Комментарии:
1. Что за глупость.. Если мне нужно обрезать начало / конец строки и т.д. зачем мне использовать Path. Объединить в первую очередь?
2. Есть ли в истории хоть один вариант использования, когда кто-нибудь хотел бы, чтобы это работало именно так??
Ответ №2:
Пути, начинающиеся с косой черты, интерпретируются как абсолютные, а не относительные. Просто обрежьте косую черту, если хотите гарантировать, что relativePath
это будет рассматриваться как относительное.
var basePath = @"\serverBaseFolder";
var relativePath = @"MyRelativeFolder";
var combinedPath = Path.Combine(basePath, relativePath.TrimStart('/', '\'));
Ответ №3:
Согласно этому документу в Path.Combine
примечании говорится, что его лучше всего использовать Path.Join()
для этого сценария, где пользователь, возможно, ввел значения. Похоже, что это было введено с .NET Core 3.0
Path.Join(basePath, relativePath);
Похоже, единственное отличие заключается в этом явном сценарии, где мы не хотим рассматривать какой-либо из путей, которые мы объединяем, как потенциальные корневые пути.
В отличие от метода Combine, метод Join не пытается использовать root для возвращаемого пути. (То есть, если path2 или path2 или path3 является абсолютным путем, метод Join не отбрасывает предыдущие пути, как это делает метод Combine.
Комментарии:
1. Это не работает, это добавляет еще одну косую черту к корневой папке. Например,
path1 = \files, path2 = filename.txt, result = \files\filename.txt
2. Это правда, что это не удаляет лишние косые черты, но в Windows и Unix (читай: практически везде) это нормально: unix.stackexchange.com/a/1919
3. Просто чтобы указать, что это недоступно в .net framework