Angenommen, Sie haben den neuen Code std::filesystem
(oder std::experimental::filesystem
) verwendet, um eine Datei zu suchen. Sie haben eine path
Variable, die den vollständigen Pfadnamen zu dieser Variablen enthält.Mit einem Dateisystem :: Pfad, wie öffnen Sie eine Datei auf eine plattformübergreifende Weise?
Wie öffne ich diese Datei?
Das albern klingen, aber betrachten die offensichtliche Antwort:
std::filesystem::path my_path = ...;
std::ifstream stream(my_path.c_str(), std::ios::binary);
Dies ist nicht garantiert zu arbeiten. Warum? Unter Windows beispielsweise lautet path::string_type
std::wstring
. So wird path::c_str
eine const wchar_t*
zurückgeben. Und std::ifstream
kann nur nehmen Pfade mit einem const char*
Typ.
Jetzt stellt sich heraus, dass dieser Code tatsächlich in VS funktioniert. Warum? Weil Visual Studio eine library extension that does permit this to work hat. Aber das ist nicht-Standard-Verhalten und daher nicht portable. Zum Beispiel habe ich keine Ahnung, ob GCC unter Windows die gleiche Funktion bietet.
Sie konnten dieses versuchen:
std::filesystem::path my_path = ...;
std::ifstream stream(my_path.string().c_str(), std::ios::binary);
Nur Windows-uns confounds wieder. Denn wenn my_path
zufällig Unicode-Zeichen enthält, sind Sie jetzt darauf angewiesen, die ANSI-Spracheinstellungen für Windows korrekt zu setzen. Und selbst das wird Sie nicht unbedingt retten, wenn der Pfad Zeichen aus mehreren Sprachen enthält, die nicht in demselben ANSI-Gebietsschema vorhanden sein können.
Boost Dateisystem hatte eigentlich ein ähnliches Problem. Aber sie haben ihre Version von iostreams erweitert, um path
s direkt zu unterstützen.
Fehle ich hier etwas? Hat das Komitee eine plattformübergreifende Dateisystembibliothek hinzugefügt, ohne einen plattformübergreifenden Weg zu Open Dateien darin hinzuzufügen?
Die Erweiterung wird sehr wahrscheinlich standardisiert [Fehlerbericht 2676] (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2676). Könnte letzte Woche passiert sein. –
Würde 'basic_ifstream streamen (mein_pfad);' funktionieren, oder fehle ich da etwas? Es ist sicherlich nicht schön ... –
chris
@chris: Nein. Der 'basic_ifstream''s Zeichentyp bezieht sich auf den Zeichentyp der * Daten * es liest/schreibt, nicht den Pfad, den es braucht. –