Используя файловую систему:: path, как вы открываете файл кросс-платформенным способом?
Скажем, вы использовали новый код std::filesystem
(или std::experimental::filesystem
) для поиска файла. У вас есть переменная path
, которая содержит полное имя пути к этой переменной.
Как открыть этот файл?
Это может показаться глупым, но рассмотрим очевидный ответ:
std::filesystem::path my_path = ...;
std::ifstream stream(my_path.c_str(), std::ios::binary);
Это не гарантируется. Зачем? Например, в Windows, path::string_type
есть std::wstring
. Поэтому path::c_str
вернет a const wchar_t*
. И std::ifstream
может принимать только пути с типом const char*
.
Теперь выясняется, что этот код действительно будет работать в VS. Зачем? Поскольку Visual Studio имеет расширение библиотеки которое позволяет это работать. Но это нестандартное поведение и, следовательно, не переносимое. Например, я понятия не имею, поддерживает ли GCC в Windows ту же функцию.
Вы можете попробовать следующее:
std::filesystem::path my_path = ...;
std::ifstream stream(my_path.string().c_str(), std::ios::binary);
Только Windows снова путает нас. Потому что, если my_path
содержит символы Unicode, то теперь вы полагаетесь на правильную настройку языка Windows ANSI. И даже это не обязательно спасет вас, если в пути произойдут символы из нескольких языков, которые не могут существовать в одном и том же локали ANSI.
У файловой системы Boost действительно была аналогичная проблема. Но они расширили свою версию iostreams, чтобы поддерживать path
напрямую.
Я что-то упустил? Помог ли комитет добавить межплатформенную библиотеку файловой системы, не добавляя кросс-платформенный способ открытия в нем файлов?
Ответы
Ответ 1
Бо Перссон отметил, что это тема отчета о дефекте стандартной библиотеки. Этот дефект был разрешен, и С++ 17 отправит, требуя реализации, где path::value_type
не char
, чтобы их типы потоков файлов принимали const filesystem path::value_type*
в дополнение к обычным версиям const char*
.