определение std :: filesystem "root_name" не работает в windows - PullRequest
0 голосов
/ 02 февраля 2019

У меня такое чувство, что стандарт файловой системы C ++ нарушен в Windows.Он в значительной степени основан на Boost.filesystem, и я только что обнаружил там серьезную проблему, которая (вероятно) также существует в std :: filesystem: https://github.com/boostorg/filesystem/issues/99

Суть - определение «root_name» и «root_directory»:

root-name (необязательно): определяет корень в файловой системе с несколькими корнями (например, «C:» или «// myserver»).В случае неоднозначности самая длинная последовательность символов, которая образует правильное корневое имя, обрабатывается как корневое имя.Стандартная библиотека может определять дополнительные корневые имена, помимо тех, которые понятны для API OS.

root-directory (необязательно): разделитель каталогов, который, если присутствует, помечает этот путь как абсолютный.Если он отсутствует (и первым элементом, отличным от корневого имени, является имя файла), то этот путь является относительным и требует другого пути в качестве исходного местоположения для разрешения имени файла.

Для этого необходимо, например, разложить "C: \ foo \ bar.txt" на:

  • root_name: "C:"
  • root_directory:"\" или "/" (это вообще имеет смысл?)
  • каталог: "foo"
  • имя_файла "bar.txt"

Проблема сейчас: Первая часть этого пути не является путем, по крайней мере, не оригинальным.Это вытекает из интерпретации в Windows:

  • «C: \» - это диск «C»
  • «C:» - это текущий рабочий каталог на диске «C»

Minor: Как интерпретировать файл "\ foo \ bar.txt" в Windows в соответствии с приведенным выше описанием?У вас есть «root_directory» (который, как ни странно, не каталог, а каталог разделитель ), но нет «root_name», следовательно, путь не может быть абсолютным, поэтому у вас нет и «root_directory».вздох.

Итак, я чувствую, что «root_name» и «root_directory» не могут быть разложены (в Windows).В «C: \ foo» у вас будет «C: \», а в «C: foo» - «C:».Или чтобы сохранить (странно определенный) «корневой_каталог», вам нужно установить декомпозицию «C: \ foo» на «C: \», «\» и «foo» и бороться с последним: это абсолютный путь?На самом деле это так: «Папка« foo »в текущем рабочем каталоге на диске C», абсолютно абсолютная, не правда ли?

Но хорошо, что вы могли бы сказать «absolute == независимо от текущего рабочего каталога»«root_directory» имеет смысл: он будет «\» для «C: \ foo» и пуст для «C: foo».

Так что вопрос: является ли стандарт неправильным в определении «C:» как«root_name» вместо «C: \» в путях типа «C: \ foo» или это просто недопустимое использование для перебора компонентов пути, ожидающих, что суммы префикса будут «действительными»?

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

То, что вам нужно, это root_path, см. Файловая система TS § 8.4.9, декомпозиция пути :

path root_path() const;

Возвращает: root_name() / root_directory()

Вот как Microsoft определяет его :

Общее для обеих системэто структура, наложенная на путь после того, как вы пройдете корневое имя.Для пути c:/abc/xyz/def.ext:

  • Корневое имя c:.
  • Корневой каталог /.
  • Корневой путьis c:/.
  • Относительный путь abc/xyz/def.ext.
  • Родительский путь c:/abc/xyz.
  • Имя файла def.ext.
  • Стебель def.
  • Расширение .ext.

Таким образом, истинно абсолютный путь начинается с root_name + root_directory или root_path.

См. Также system_complete(p) для разрешения текущего каталога на других дисках:

Эффекты: Составляет абсолютный путь от p, используя те же правила, которые используются операционной системой для разрешения пути, переданного в качестве аргумента имени файла в стандартные функции открытия библиотеки.

[ Пример: Для POSIXна основе операционных систем system_complete(p) имеет ту же семантику, что и absolute(p, current_path()).

Для операционных систем на базе Windows system_complete(p) имеет ту же семантику, что и absolute(p, current_path()), если p.is_absolute() || !p.has_root_name() или p и база имеетто же самое root_name().В противном случае он действует, как absolute(p, cwd) - это текущий каталог для диска p.root_name().Это будет текущий каталог для этого диска в последний раз, когда он был установлен, и, таким образом, он может быть оставшимся от предыдущей программы, запущенной командным процессором.Хотя эта семантика полезна, они могут быть удивительными. - конец примера ]

0 голосов
/ 02 февраля 2019

Ваша интерпретация файловой системы Windows неверна.Каталог C:\ является корневым каталогом диска «C», а не «диска« C »».Это отличается от C:, который является текущим каталогом диска "C".Просто попробуйте использовать оболочку Windows и посмотрите, как C:<stuff> ведет себя относительно C:\<stuff>.Оба будут получать доступ к данным на этом диске, но оба будут делать это, начиная с разных каталогов.

Подумайте об этом в Windows следующим образом:

  • C: означает «Перейти к«Текущий каталог диска C».
  • \ в начале пути (после любых корневых имен) означает «Перейти в корневой каталог текущего диска».
  • foo\ означает «Перейдите в каталог с именем« foo »в любой директории, в которой мы сейчас находимся».
  • bar.txt означает «Файл с именем« bar.txt »в любой директории, в которой мы на данный момент находимся».

Следовательно, C:\foo\bar.txt" означает: перейдите в текущий каталог диска C, затем перейдите в корневой каталог C, затем перейдите в каталог 'foo' корневого каталога C, затем получите доступфайл 'bar.txt' в каталоге 'foo' корневого каталога C.

Аналогично, C:foo\bar.txt означает: перейдите в текущий каталог диска C, затем перейдите в 'foo'каталог текущей директории C, затем откройте файл 'bar.txt' в 'foo 'каталог текущего каталога C.

Так работают пути Windows.Вот что значит печатать эти вещи в оболочке Windows.И, таким образом, именно так были разработаны пути файловой системы Boost / std.

Но вы могли бы сказать, что "absolute == не зависит от текущего рабочего каталога"

Ноэто не то, как файловая система std определяет концепцию «абсолютного пути» :

Абсолютный путь Путь, который однозначно определяет местоположение файла без ссылки надополнительная стартовая локация.Элементы пути, которые определяют, является ли он абсолютным, зависят от операционной системы.

Таким образом, «относительный» и «абсолютный» зависят от реализации.В Windows путь не является абсолютным, если он не содержит и корневого имени и корневого каталога.В реализации файловой системы Windows path("\foo\bar.txt").is_absolute() будет ложным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...