2016-06-30 4 views
15

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_typestd::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?

+1

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. –

+0

Würde 'basic_ifstream streamen (mein_pfad);' funktionieren, oder fehle ich da etwas? Es ist sicherlich nicht schön ... – chris

+0

@chris: Nein. Der 'basic_ifstream''s Zeichentyp bezieht sich auf den Zeichentyp der * Daten * es liest/schreibt, nicht den Pfad, den es braucht. –

Antwort

7

Bo Persson wies darauf hin, dass dies das Thema einer standard library defect report ist. Dieser Fehler wurde behoben, und C++ 17 wird geliefert, wobei Implementierungen erforderlich sind, bei denen path::value_type nicht char ist, damit die Datei-Stream-Typen const filesystem path::value_type* s zusätzlich zu den üblichen const char*-Versionen annehmen.

+2

Es hat nicht. Obwohl es wahrscheinlich behoben wird, bevor C++ 17 veröffentlicht wird. –

+0

Geöffnet: 2017-03-09 (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2943) –

Verwandte Themen