
ghc::filesystem::ifstream , ghc::filesystem::ofstream , ghc::filesystem::fstreamghc::filesystem::u8arguments Dies ist eine nur Header-Einzel-File std::filesystem -Helferbibliothek, basierend auf den Spezifikationen von C ++ 17 und C ++ 20, jedoch für C ++ 11, C ++ 14, C ++ 17 oder C ++ 20 implementiert (dicht dem C ++ 17-Standard mit nur wenigen dokumentierten dokumentierten Ausnahmen). Es wird derzeit auf MacOS 10.12/10.14/10.15/11.6, Windows 10, Ubuntu 18.04, Ubuntu 20.04, Centos 7, Centos 8, FreeBSD 12, Alpine Arm/ARM64 Linux und Solaris 10 getestet, sollte aber auch an anderen Systemen arbeiten, so lange Sie zumindest einen C ++ 11 -Kompilierer haben. Es sollte mit Android NDK, EmScripten und ich sogar berichtet, dass es auf iOS (innerhalb von Sandboxing -Einschränkungen) und mit V15 verwendet wurde. Die Unterstützung von Android NDK, EMSCIPTEN, QNX und seit 1.5.14 GNU/Hurd und Haiku wird nicht durch automatisierte Tests unterstützt, aber PRS- und Bug -Berichte sind auch für diejenigen willkommen und es wird berichtet, dass sie arbeiten. Es ist natürlich in seinem eigenen Namespace ghc::filesystem ein reguläres std::filesystem nicht zu stören, wenn Sie es in einer gemischten C ++ 17 -Umgebung verwenden (was möglich ist).
Die Testabdeckung liegt weit über 90%und beginnend mit V1.3.6 und in V1.5.0 wurde mehr Zeit in das Benchmarking und die Optimierung von Teilen der Bibliothek investiert. Ich werde versuchen, einige Teile weiterhin zu optimieren und andere zu refaktor, um sie zu verbessern, solange es keine zusätzlichen C ++ 17/C ++ 20 -Kompatibilitätsprobleme einführt. Feedback ist immer willkommen. Öffnen Sie einfach ein Problem, wenn Sie sehen, dass etwas fehlt oder falsch ist oder sich nicht wie erwartet verhält, und ich kommentiere.
Ich brauche oft eine Dateisystemfunktionalität, hauptsächlich fs::path , aber auch Verzeichniszugriff, und wenn ich anfange, C ++ 11 zu verwenden, habe ich dieses Sprachaktualisierung verwendet, um zu versuchen, meine Abhängigkeiten von Drittanbietern zu reduzieren. Ich konnte das meiste von dem fallen lassen, was ich verwendet habe, verpasste aber immer noch einige Dinge, die ich zum Spaß implementieren begann. Ursprünglich habe ich diese Helfer auf meinen eigenen Coding- und Namenskonventionen gestützt. Als C ++ 17 abgeschlossen war, wollte ich diese Schnittstelle verwenden, aber es dauerte eine Weile, um mich zu drängen, um meine Klassen zu konvertieren.
Die Implementierung basiert eng auf Kapitel 30.10 aus dem C ++ 17 -Standard, und ein Entwurf in der Nähe dieser Version arbeitet den Entwurf von N4687. Nach der Standardisierung von C ++ 17 enthält es jedoch die neuesten Änderungen der Dateisystem -Schnittstelle im Vergleich zum Arbeitsentwurf N4659. Wenn es mit V1.4.0 starrt, passt es bei kompiliertem C ++ 20 die Änderungen gemäß Pfadsortierreihenfolge und std::u8string -Handhabung aus dem Arbeitsentwurf N4860 an.
Ich möchte den Leuten danken, die an der Verbesserung von C ++ arbeiten. Ich mochte sehr, wie sich die Sprache mit C ++ 11 und den folgenden Standards entwickelt hat. Machen Sie die gute Arbeit weiter!
Wenn Sie sich fragen, wofür ghc steht, sind es einfach gulraks helper classes , ja, ich weiß, nicht sehr fantasievoll, aber ich wollte einen kurzen Namespace und ich benutze ihn in einigen meiner privaten Klassen (also hat es nichts mit Haskell zu tun , sorry den Namen Clash).
ghc::filesystem wird auf macOS entwickelt, aber CI wurde auf MacOS, Windows, verschiedenen Linux -Verteilungen, FreeBSD und beginnend mit V1.5.12 auf Solaris getestet. Es sollte mit einem C ++-11-fähigen Compiler auf einem von diesen funktionieren. Außerdem gibt es einige Überprüfungen, um hoffentlich besser an Android zu arbeiten, aber da ich derzeit nicht mit dem Android NDK testet, würde ich es noch nicht als unterstützte Plattform bezeichnen, dies gilt für die Verwendung mit EMSCIPTEN. Es ist jetzt Teil der erkannten Plattformen, ich habe die offensichtlichen Probleme behoben und einige Tests damit durchgeführt, also sollte es in Ordnung sein. Alles in allem sehe ich nicht, dass es std::filesystem ersetzt wird, in dem die vollständige C ++ 17 oder C ++ 20 verfügbar ist. Es wird nicht versucht, ein "besseres" std::filesystem zu sein, nur ein fast Drop-In, wenn Sie es nicht verwenden können (mit Ausnahme der UTF-8).
Wichtig: Diese Implementierung folgt der Philosophie "UTF-8 überall", da alle std::string Instanzen wie std::u8string codierend und als in UTF-8 interpretiert werden. Die std::u16string wird als UTF-16 angesehen. Weitere Informationen finden Sie unter Unterschiede in der API .
Unit -Tests werden derzeit durchgeführt mit:
Der Header verfügt über eine Reihe von Einheitentests und verwendet CMake als Build-Tool und Catch2 als Test-Framework. Alle Tests sind in CMake registriert, sodass der CTest -Kommando zum Ausführen der Tests verwendet werden kann.
Alle Tests gegen diese Implementierung sollten erfolgreich sein, abhängig von Ihrer Umgebung kann es sein, dass es einige Warnungen gibt, z. B. wenn Sie kein Recht haben, Symlinks unter Windows zu erstellen, oder zumindest der Test denkt, aber diese sind nur informativ.
Erstellen Sie die Tests aus dem Projektverzeichnis unter macOS oder linux nur:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
ctestDies generiert die Testbinärdateien, die die Tests ausführen, und der letzte Befehl führt sie aus.
Wenn der Standard -Compiler ein GCC 8 oder neuer oder neuer oder neuer ist, erstellt er zusätzlich eine Version des Tests Binärer, die gegen GCCs/Klangs std::filesystem -Implementierung mit dem Namen std_filesystem_test als zusätzlicher Konformitätstest zusammengestellt wurden. Idealerweise sollten alle Tests mit allen Dateisystem -Implementierungen kompilieren und erfolgreich sein, aber in Wirklichkeit gibt es einige Unterschiede im Verhalten, manchmal aufgrund des Interpretationsraums im Standard, und es kann auch Probleme in diesen Implementierungen geben.
Die neueste Version ist v1.5.14 und Quellarchive finden Sie hier.
Die neueste Version vor dem Nativ-Backend ist v1.4.0 und Quellarchive finden Sie hier.
Die neueste Version Pre-C ++ 20-Support-Version ist V1.3.10 und Quellarchive finden Sie hier.
Derzeit empfängt nur die neueste Minor -Release -Version Fehler. Wenn möglich, sollten Sie die neueste Version verwenden.
Da ghc::filesystem zunächst eine Bibliothek nur für Header ist, sollte es ausreichen, den Header oder das ghc/filesystem.hpp include/ghc -Verzeichnis in Ihren Projektordner zu kopieren oder Ihren Pfad zu diesem Ort zu zeigen und einfach das filesystem.hpp einzuschließen.
Alles befindet sich im Namespace ghc::filesystem . Eine Möglichkeit, es nur als Fallback zu verwenden, könnte sein:
# if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
# if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
# define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
# ifdef __APPLE__
# include < Availability.h >
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
# if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
# undef GHC_USE_STD_FS
# endif
# endif
# endif
# endif
# ifdef GHC_USE_STD_FS
# include < filesystem >
namespace fs = std::filesystem;
# else
# include " filesystem.hpp "
namespace fs = ghc::filesystem;
# endif Wenn Sie auch den fstream -Wrapper mit path als Fallback verwenden möchten, können Sie möglicherweise verwenden:
# if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
# if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
# define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
# ifdef __APPLE__
# include < Availability.h >
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
# if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
# undef GHC_USE_STD_FS
# endif
# endif
# endif
# endif
# ifdef GHC_USE_STD_FS
# include < filesystem >
namespace fs {
using namespace std ::filesystem ;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
# else
# include " filesystem.hpp "
namespace fs {
using namespace ghc ::filesystem ;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
# endif Jetzt haben Sie zB fs::ofstream out(somePath); Und es ist entweder der Wrapper oder der C ++ 17 std::ofstream .
Beachten Sie, dass es als Header-Bibliothek nicht versteckt ist, dass es ein System verwendet, das einen "Umschadung" Ihres globalen Namespace. Verwenden Sie den Ansatz für Weiterleitungen/Implementierungsvorschriften (siehe unten), um dies zu vermeiden. Für Windows benötigt es Windows.h und es könnte eine gute Idee sein, WIN32_LEAN_AND_MEAN oder NOMINMAX vor dem Einfügen filesystem.hpp oder fs_std.hpp -Header zu definieren, um die Verschmutzung Ihres globalen Namespace und die Kompilierung der Zeit zu verringern. Sie werden nicht von ghc::filesystem definiert, um eine Kombination mit Kontexten zu ermöglichen, in denen die vollständige Windows.h benötigt wird, z. B. für UI -Elemente.
Hinweis: Es gibt einen zusätzlichen Header mit dem Namen ghc/fs_std.hpp , der diese dynamische Auswahl einer Dateisystem -Implementierung implementiert, die Sie anstelle von ghc/filesystem.hpp einschließen können, wenn Sie std::filesystem erhalten möchten, wo es verfügbar ist, und ghc::filesystem wo nicht.
Alternativ kann ab V1.1.0 ghc::filesystem auch durch Einbeziehung einer von zwei zusätzlichen Wrapper -Headern verwendet werden. Diese ermöglichen es, an den meisten Stellen eine weitergeleitete Version ( ghc/fs_fwd.hpp ) einzuschließen, während die Implementierungsdetails in einer einzelnen CPP -Datei versteckt sind, die ghc/fs_impl.hpp enthält, um den erforderlichen Code zu implementieren. Wenn Sie ghc::filesystem auf diese Weise verwenden, stellt sicher, dass das System in der CPP -Datei nur aus sichtbar ist und alle anderen Stellen sauber sind.
Beachten Sie, dass es derzeit nicht unterstützt wird, die Implementierung in einem Windows-DLL zu verbergen, da eine DLL-Schnittstelle mit C ++-Standardvorlagen in Schnittstellen ein anderes Tier ist. Wenn jemand bereit ist, es auszuprobieren, kann ich eine PR integrieren, aber gerade daran arbeite, dass ich selbst keine Priorität hat.
Wenn Sie den Ansatz für Weiterleitungen/Implementierungen verwenden, können Sie dennoch das dynamische Schalter wie diesen verwenden:
# if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
# if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
# define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
# ifdef __APPLE__
# include < Availability.h >
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
# if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
# undef GHC_USE_STD_FS
# endif
# endif
# endif
# endif
# ifdef GHC_USE_STD_FS
# include < filesystem >
namespace fs {
using namespace std ::filesystem ;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
# else
# include " fs_fwd.hpp "
namespace fs {
using namespace ghc ::filesystem ;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
# endif In der Implementierung des Verstecks von CPP können Sie verwenden (bevor alle inklusive ghc/fs_fwd.hpp enthält, um Vorrang zu haben:
# if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
# if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
# define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
# ifdef __APPLE__
# include < Availability.h >
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
# if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
# undef GHC_USE_STD_FS
# endif
# endif
# endif
# endif
# ifndef GHC_USE_STD_FS
# include " fs_impl.hpp "
# endif Hinweis: Es gibt zusätzliche Helfer -Header mit dem Namen ghc/fs_std_fwd.hpp und ghc/fs_std_impl.hpp , die diese Technik verwenden, sodass Sie sie einfach einfügen können, wenn Sie die Implementierung des Dateisystems dynamisch auswählen möchten.
Ab V1.1.0 ist es möglich, ghc::filesystem als Git add_subdirectory() Submodule hinzuzufügen, das Verzeichnis target_link_libraries(your-target ghc_filesystem) CMakeLists.txt zu fügen #include <ghc/filesystem.hpp>
Die CMakeLists.txt bietet einige Optionen, um sein Verhalten anzupassen:
GHC_FILESYSTEM_BUILD_TESTING - TESTS COMPILE -TESTEN, DER STATION wird OFF , wenn es als Submodul verwendet wird, ON .GHC_FILESYSTEM_BUILD_EXAMPLES - kompilieren Sie die Beispiele, die Standardeinstellung wird OFF ON wenn sie als Submodul verwendet werden.GHC_FILESYSTEM_WITH_INSTALL - Installieren Sie das Erstellen von Installation hinzufügen. Die Standardeinstellung wird OFF ON wenn sie als Submodul verwendet werden.GHC_FILESYSTEM_BUILD_STD_TESTING - kompilieren Sie std_filesystem_test , die Variante der Testsuite, die gegen std::filesystem ausgeführt wird, und nicht zu GHC_FILESYSTEM_BUILD_TESTING . Dies geschieht nur, wenn der Compiler als in der Lage erfasst wird, dies zu tun.GHC_FILESYSTEM_TEST_COMPILE_FEATURES kann auf eine Liste von Funktionen eingestellt werden, um CMAKE_CXX_COMPILE_FEATURES zu überschreiben, wenn die Erkennung von C ++ 17 oder C ++ 20 für zusätzliche Tests nicht funktioniert (z. B. cxx_std_20 , um das Erstellen eines filesystem_test_cpp20 mit C ++ 20) zu erstellen.Bitte verwenden Sie Hedronvision/Bazel-CC-Filesystem-Backport, mit dem alles automatisch für Sie eingerichtet wird.
Es gibt eine Version MACRO GHC_FILESYSTEM_VERSION , falls zukünftige Änderungen möglicherweise dazu führen könnten, dass sie auf die Version reagieren, aber ich habe nicht vor, etwas zu brechen. Es ist die Version als Dezimalzahl (major * 10000 + minor * 100 + patch) .
Hinweis: Nur Patch -Versionen werden für Veröffentlichungen verwendet, und für die Arbeit an der nächsten Version werden nur für den Commits verwendet.
In dieser Veröffentlichung gibt es fast keine Dokumentation, da jede Dokumentation std::filesystem neben den wenigen Unterschieden im nächsten Abschnitt funktionieren würde. Sie können also zu https://en.cppreference.com/w/cpp/filesystem gehen, um eine Beschreibung der Komponenten dieser Bibliothek zu beschreiben.
Beim Kompilieren mit C ++ 11, C ++ 14 oder C ++ 17 folgt die API nach Möglichkeit dem C ++ 17 -Standard, mit der Ausnahme, dass std::string_view -Parameter nur auf C ++ 17 unterstützt werden. Beim Kompilieren mit C ++ 20 ist ghc::filesysytem standardmäßig mit der C ++ 20 -API mit den Schnittstellen char8_t und std::u8string und der veralteten fs::u8path -Factory -Methode.
HINWEIS: Wenn die C ++ 17 -API auch im C ++ 20 -Modus erzwungen werden sollte, verwenden Sie die Define GHC_FILESYSTEM_ENFORCE_CPP17_API . Auch dann ist es möglich fws::path von std::u8string zu erstellen, aber fs::path::u8string() und fs::path::generic_u8string() return normal utf-8 codiert std::string , also code für c ++ 17 funktionieren immer noch mit ghc::filesystem , wenn mit c ++ c ++ c ++ 20 20.
Die einzigen Ergänzungen zum Standard sind hier dokumentiert:
ghc::filesystem::ifstream , ghc::filesystem::ofstream , ghc::filesystem::fstream Dies sind einfache Wrapper um std::ifstream , std::ofstream und std::fstream . Sie fügen einfach eine open() -Methode und einen Konstruktor mit einem ghc::filesystem::path -Argument hinzu, da die fstream -Varianten in C ++ 17 sie haben.
ghc::filesystem::u8argumentsDies ist eine Helferklasse, die derzeit nach der UTF-8-Codierung auf Nicht-Windows-Plattformen überprüft wird, unter Windows jedoch die Befehlszeilenargumente als Unicode-Zeichenfolgen aus dem Betriebssystem mit abgerufen
::CommandLineToArgvW (::GetCommandLineW(), &argc) und konvertiert sie dann in UTF-8 und ersetzt argc und argv . Es ist eine schützenartige Klasse, die ihre Änderungen zurückkehrt, wenn sie aus dem Zielfernrohr gehen.
Die grundlegende Verwendung ist also:
namespace fs = ghc::filesystem;
int main ( int argc, char * argv[])
{
fs::u8arguments u8guard (argc, argv);
if (!u8guard. valid ()) {
std::cerr << " Bad encoding, needs UTF-8. " << std::endl;
exit (EXIT_FAILURE);
}
// now use argc/argv as usual, they have utf-8 encoding on windows
// ...
return 0 ;
} Auf diese Weise ist argv UTF-8 codiert, solange der Geltungsbereich von main gültig ist.
HINWEIS: Bei MacOS wird beim Debuggen unter Xcode der Code false zurückgegeben, da Xcode die Anwendung mit US-ASCII als Codierung startet, unabhängig davon, welche Codierung tatsächlich verwendet wird, und sogar das Einstellen LC_ALL im Produktschema ändert nichts. Ich muss das noch untersuchen.
Da diese Implementierung auf vorhandenen Code aus meinen privaten Helferklassen basiert, hat sie einige Einschränkungen davon abgeleitet. Ausgehend von v1.5.0 die meisten Unterschiede zwischen diesem und dem Standard C ++ 17/C ++ 20 API, wobei sie entfernt wurden.
Diese Implementierung hat ein schaltbares Verhalten für die LWG -Defekte Nr. 2682, Nr. 2935, Nr. 2936 und Nr. 2937. Das aktuell ausgewählte Verhalten (ab V1.4.0) folgt #2682, #2936, #2937, aber nicht folgt # fs::is_directory , da ich der Meinung bin, dass es ein Fehler ist, keinen Fehler auf einem create_directory() oder create_directories() wobei eine reguläre Datei gleichermaßen die Erstellung des Erschaffens verpflichtet. gearbeitet. Der intuitivere Ansatz zur Erstellung von Verzeichnissen bei der Behandlung einer Datei mit diesem Namen als Fehler wird auch durch das neuere Papier WG21 P1164R0 befürwortet. Die Revision P1161R1 wurde auf Kona 2019 vereinbart, dass Merge und GCC inzwischen auf den folgenden Vorschlag umgestellt wurden (GCC #86910).
// methods in ghc::filesystem::path:
path& operator +=(basic_string_view<value_type> x);
int compare (basic_string_view<value_type> s) const ; Diese werden nicht unter C ++ 11 und C ++ 14 implementiert, da keine std::basic_string_view verfügbar ist und ich diese Implementierung in sich geschlossen und nicht ein vollständiges C ++ 17-Upgrade für C ++ 11/14 schreiben wollte. Beginnend mit v1.1.0 werden diese beim Kompilieren von ghc::filesystem unter C ++ 17 von C ++ 20 unterstützt.
Beginnend mit v1.5.2 ghc::filesystem versucht die Verwendung von std::experimental::basic_string_view wo die Erkennung von der Verfügbarkeit ist. Wenn Sie eine basic_string_view -kompatible C ++ 11 -Implementierung haben, kann es anstelle von std::basic_string_view verwendet werden, indem GHC_HAS_CUSTOM_STRING_VIEW definiert und die Implementierung in den ghc::filesystem -Namespace mit:
namespace ghc {
namespace filesystem {
using my::basic_string_view;
}
}Vor der Einbeziehung des Dateisystem -Headers.
Um nicht von externen Bibliotheken von Drittanbietern abhängig zu sein und dennoch tragbar und kompakt zu bleiben, folgt diese Implementierung der Philosophie "UTF-8 Everywhere" darin, dass alle std::string Instanzen wie std::u8string codierend und wie in UTF-8 interpretiert werden. Das std::u16string wird als UTF-16 und std::u32string als Unicode-CodePoints angesehen. Abhängig von der Größe von std::wstring -Zeichen wird std::wstring als UTF-16 (z. B. Windows) oder char32_t Unicode-CodePoints (derzeit alle anderen Plattformen) behandelt.
Beginnend mit V1.5.0 ghc::filesystem folgt dem C ++ 17 -Standard bei der Verwendung wchar_t und std::wstring unter Windows als die interne Typen, die für die Pfaddarstellung verwendet werden. Es ist immer noch möglich, das alte Verhalten zu erhalten, indem Sie GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE definieren und filesystem::path::string_type als std::string und filesystem::path::value_type als wchar_t erhalten.
Wenn Sie eine Windows-API mit v1.5.0 und höher aufrufen müssen, verwenden Sie einfach den W-Varianten des Windows-API-Aufrufs (z. B. GetFileAttributesW(p.c_str()) ).
HINWEIS: Wenn Sie das alte Verhalten verwenden, indem Sie GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE definieren, verwenden Sie das path::wstring() (z. B. GetFileAttributesW(p.wstring().c_str()) ). Dies gibt Ihnen die Unicode -Variante unabhängig vom UNICODE -Makro und erleichtert den Code zwischen Windows, Linux und MacOS und funktioniert mit std::filesystem und ghc::filesystem .
std::string path::u8string () const ;
std::string path::generic_u8string () const ;
vs.
std::u8string path::u8string () const ;
std::u8string path::generic_u8string () const ; Der Rückgabetyp dieser beiden Methoden hängt vom verwendeten C ++ - Standard ab und wenn GHC_FILESYSTEM_ENFORCE_CPP17_API definiert ist. Auf C ++ 11, C ++ 14 und C ++ 17 oder wenn GHC_FILESYSTEM_ENFORCE_CPP17_API definiert ist, ist der Rückgabetyp std::string und auf c ++ 20 ohne das Define ist es std::u8string .
Ich habe einen Wiki -Eintrag über eine Menge Verhaltensunterschiede zwischen verschiedenen std::filesystem -Implementierungen erstellt, die hier zu einer Erwähnung führen können. Diese Readme versucht jedoch nur, die Unterschiede für die Auswahl der Designauswahl zwischen ghc::filesystem und diesen zu beheben. Ich versuche von Zeit zu Zeit die Wiki -Seite zu aktualisieren.
Alle zusätzlichen Beobachtungen sind willkommen!
Seit v1.5.0 die vollständige innere Mechanik dieser Implementierungen fs::path , wo sich als interne Darstellung in das native Format geändert hat. Erstellen eines gemischten Slash fs::path -Pfadobjekts unter Windows (zB mit "C:foo/bar" ) führt über native() und "C:/foo/bange" über generic_string() api einen sauberen Pfad mit "C:foobar" und "C:/foo/bar" . Auf allen Plattformen werden redundante zusätzliche Separatoren entfernt, auch wenn dies nicht durch die Standard- und andere Implementierungen erzwungen wird.
Zusätzlich folgt diese Implementierung dem Standardvorschlag, POSIX-Pfade des Formulars "//host/path" und USC-Pfad auf Windows zu verarbeiten, ebenfalls einen Root-NAME (z. B. "//host" ). Die GCC -Implementierung entschied sich nicht dafür, dies beim Testen auf Ubuntu 18.04 und MacOS mit GCC 8.1.0 oder Clang 7.0.0 zu tun. Dieser Unterschied wird als Warnungen unter std::filesystem angezeigt. Dies führt zu einer Änderung des Algorithmus, der im Standard für operator/=(path& p) beschrieben wird, wobei jeder Pfad p mit p.is_absolute() auf eine Zuordnung abgebaut wird, während diese Implementierung die Ausnahme hat, wo *this == *this.root_name() und p == preferred_separator ein normaler Anhang ermöglicht wird, um zu ermöglichen, zuzulassen, um:
fs::path p1 = " //host/foo/bar/file.txt " ;
fs::path p2;
for ( auto p : p1) p2 /= p;
ASSERT (p1 == p2);Für alle nicht veranstalteten Pfade entspricht das Verhalten dem vom Standard beschriebenen.
Als symbolische Links unter Windows, die mehr oder weniger unterstützt werden, da Windows Vista (mit einigen strengen Sicherheitsbeschränkungen) und seit einem früheren Aufbau von Windows 10, wenn der "Entwicklermodus" aktiviert ist, werden zum Zeitpunkt des Schreibens (2018) selten verwendet.
Die Windows ACL -Berechtigungsfunktion übersetzt sich schlecht in die in der Schnittstelle von C ++ 17 Dateisystem verwendete POSIX -Berechtigungsmaske. Die im file_status zurückgegebenen Berechtigungen werden daher derzeit für den user -Level synthetisiert und in die group und other -level kopiert. Es besteht immer noch ein gewisses Potenzial für eine stärkere Interaktion mit dem Windows -Berechtigungssystem, aber derzeit führt das Einstellen oder Lesen von Berechtigungen mit dieser Implementierung mit Sicherheit nicht zum erwarteten Verhalten.
extension() gab ein nicht leeres Ergebnis für den Verzeichnisnamen ".." zurück.ghcFilesystem::ghc_filesystem ist jetzt bedingungslos festgelegtstem() , filename() und extension() von fs::path würde ein falsches Ergebnis zurückgeben, wenn ein Dickdarm im Dateinamen wärefs::last_write_time(path, time, ec) Setter auf iOS, tvos und watchosfs::directory_entry::refresh() nun konsequent mit status() wird Symlinks nicht an nicht existierende Ziele angewendet, aber file_type::not_foundEINTR in der Iteration von POSIX -Verzeichnissen zu verarbeiten und Dateikopie zu kopieren, um Fehler in Netzwerkdateisystemen zu vermeidenfs::copy_file() kopiert nun auch die Berechtigungenfs::copy_file() Ignorieren Sie die Option skip_existing .GHC_NO_DIRENT_D_TYPE auf Systemen, die dirent::d_type und die Konfiguration und Tests behoben haben, um Solaris als neue Plattform zu unterstützen.PATH_MAX hat, ist einer definiert.fs::remove_all jetzt löscht nur symbolische Links, anstatt ihnen zu folgen.fs::space , in dem ein numerischer Überlauf in einer Multiplikation auftreten kann.fs::create_directories unter Windows nicht mehr auf langen Dateinamen bricht.ghc::filesystem behandeltem Ordner/Volumes fälschlicherweise als Symlinks und führt fs::canonical dazu, auf Pfaden zu scheitern, die diese enthalten.recursive_directory_iterator wird nicht versucht, tote Symlinks zu betreten.fs::remove fehlgeschlagen, als der Pfad auf einen schreibgeschützten Eintrag hinwies, siehe auch (Microsoft/STL #1511) für das entsprechende Problem in std::fs unter Windows.GHC_NO_DIRENT_D_TYPE ermöglicht die OS -Erkennung, um Systeme ohne dirent.d_type zu unterstützen.string_view hinzugefügt, wenn Clang mit libstdc ++ erkannt wird.<Availability.h> vor <ghc/fs_std.hpp> oder <ghc/fs_std_fwd.hpp> / <ghc/fs_std_impl.hpp> enthalten war.std::filesystem Dateisystemfunktionen unterstützt und durch die Tag-ähnlichen Kapitelnamen ersetzt wurden, die (meistens) über die Versionen konsistent bleiben.recursive_directory_iterator über große Bäume, die jetzt irgendwo zwischen libc ++ und libstdc ++ sind.ghc::filesystem unterstützt jetzt eine vorläufige Unterstützung für Cygwin. Änderungen, die vorgenommen wurden, damit die Tests erfolgreich zusammengestellt und ausgeführt werden können (getestet mit GCC 10.2.0), Feedback und zusätzlichen PRS willkommen, da es derzeit nicht Teil der CI -Konfiguration ist.GHC_FILESYSTEM_BUILD_STD_TESTING hinzugefügt, um den zusätzlichen Build von std::filesystem -Versionen der Tests für den Vergleich und die Möglichkeit zu überschreiben, GHC_FILESYSTEM_TEST_COMPILE_FEATURES CMAKE_CXX_COMPILE_FEATURES zu verwenden.directory_entry für das recursive_directory_iterator .wchar_t war nicht in der Liste der unterstützten Zeichentypen auf Nicht-Windows-Backends.string_view -Unterstützung verwendet <string_view> oder <experimental/string_view> wenn verfügbar, und ermöglicht die Verwendung von benutzerdefinierter basic_string_view beim Definieren von GHC_HAS_CUSTOM_STRING_VIEW und importieren der String -Ansicht in den ghc::filesystem Dateisystem vor dem Dateisystem.std::filesystem -Tests jetzt mit -lrt , um Probleme zu vermeiden.fs::hard_link_count fehlgeschlagen aufgrund des Verhaltens von Dateisystemen, wurde der Testfall angepasst, um dies zu berücksichtigen.GHC_FS_API und GHC_FS_API_CLASS werden jetzt geehrt, wenn sie von außen festgelegt werden, um eine Verhaltensüberschreibung zu ermöglichen.make install .GHC_FILESYSTEM_BUILD_TESTING , GHC_FILESYSTEM_BUILD_EXAMPLES und GHC_FILESYSTEM_WITH_INSTALL add_subdirectory in dem implementiert wurde, implementiert, verboten, sie erneut einzustellen, um sie erneut einzustellen.fs::path wurde ursprünglich aus der posix -basierten Implementierung erstellt, indem die eingehenden und ausgehenden Saiten angepasst wurden. Dies führte zu einem veränderlichen Cache in fs::path unter Windows, der von Natur aus nicht mit Fadenfunktionen war, selbst für const Methoden. Um einer suboptimalen Lösung keine zusätzlichen Patches hinzuzufügen, habe ich diesmal den path überarbeitet, um native Pfadrepräsentation zu speichern. Dies änderte viel Code, aber in Kombination mit wchar_t als value_type half dabei, viel Konvertierung für Anrufe an Win-API zu vermeiden.fs::path::native() und fs::path::c_str() können jetzt nicht als Standardmandate noexceptwchar_t ist jetzt die Standardeinstellung für fs::path::value_type und std::wstring ist die Standardeinstellung für fs::path::string_type .const Methoden von fs::path ist kein Problem mehrGHC_WIN_DISABLE_AUTO_PREFIXES für alle anderen Arten von Präfixen oder Namespaces deaktiviert werden. Das Verhalten folgt dem von MSVC std::filesystem::pathchar / std::string -basierte Ansatz für Windows noch benötigt wird, kann er mit GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE aktiviert werdenfs::file_status unterstützt jetzt operator== in std::filesystem mit C ++ 20 eingeführt.fs::path::parent_path() hatte ein Leistungsproblem, da es immer noch einen auf Schleifen basierenden Ansatz verwendete, um die Eltern aus Elementen neu zu erstellen. Dies schuf viele Zeiträume und war auf langen Wegen zu langsam.char8_t und std::u8string werden unterstützt, wo Source der Parametertyp istfs::path::u8string() und fs::path::generic_u8string() geben nun ein std::u8string zurück<=> wird jetzt für fs::path unterstütztGHC_FILESYSTEM_ENFORCE_CPP17_API ghc::filesystem fällt auf den alten fs::path::u8string() und fs::path::generic_u8string() API, wenn bevorzugtfs::proximate(p, ec) wobei der interne Aufruf an fs::current_path() die error_code -Variante nicht verwendete und mögliche Ausnahmen warf, anstatt ec festzulegen.LWG_2936_BEHAVIOUR ist jetzt standardmäßig eingeschaltet.Source , die String -Ansichten sind.constexpr .__MAC_OS_X_VERSION_MIN_REQUIRED um sicherzustellen, dass std::filesystem nur auf MacOS ausgewählt wird, wenn das Bereitstellungsziel mindestens Catalina ist.directory_iterator und der recursive_directory_iterator ein Problem mit der Option skip_permission_denied , die zur Unfähigkeit führt, SIP -geschützte Ordner auf macOS zu überspringen._MSVC_LANG wird jetzt verwendet, wenn sie zusätzlich zu __cplusplus in den Help -Headern verfügbar sind, damit sie auch dann arbeiten können, wenn /Zc:__cplusplus nicht verwendet wird.false auf fs::exists oder nicht auf fs::status . Namenswege werden nicht mehr gefiltert.TestAllocator in filesystem_test.cpp erfüllt, um die Anforderungen für die Erstellung von CentOS 7 mit devtoolset-9 zu erfüllen. CentOS 7 und CentOS 8 sind jetzt Teil der CI -Builds.LWG_2936_BEHAVIOUR hinzu, mit dem die Post C ++ 17 fs::path::compare aktiviert werden kann, wobei der Vergleich so ist, als wäre es ein Element -Wise -Pfad -Vergleich, wie in LWG 2936 und C ++ 20 beschrieben [fs.path.compare] . Es ist standardmäßig in v1.3.6 ausgestattet und startet ab V1.4.0, da es die Bestellung ändert.wchar_t -Versionen von std::fstream von ghc::filesystem::fstream wrappers unter Windows, wenn GCC mit LIBC ++ verwendet wird.fs::directory_options::skip_permission_denied und anfängliche Unterstützung für die Kompilierung mit EMSCIPTEN.ghc::filesystem unterstützt jetzt die Verwendung in Projekten mit deaktivierten Ausnahmen. API -Signaturen mit Ausnahmen für die Fehlerbehandlung sind in diesem Modus nicht verfügbar. Vielen Dank für die PR (dies wird Nr. 60 und Nr. 43 gelöst)ERROR_FILE_TOO_LARGE -Konstante fehlschlagen.fs::lexically_relative ignorierte den nachfolgenden Schrägstrich auf dem Basisparameter, danke für PR #57.fs::create_directories returned true when nothing needed to be created, because the directory already existed.error_code was not reset, if cached result was returned.fs::path from a stream.timespec fields to avoid warnings.ghc::filesystem is re-licensed from BSD-3-Clause to MIT license. (see #47)fs::rename on Windows didn't replace an existing regular file as required by the standard, but gave an error. New tests and a fix as provided in the issue was implemented.fs_fwd.hpp or fs_std_fwd.hpp there was a use of DWORD in the forwarding part leading to an error if Windows.h was not included before the header. The tests were changed to give an error in that case too and the useage of DWORD was removed.GetProcAddress gave a warning with -Wcast-function-type on MSYS2 and MinGW GCC 9 builds.CMakeLists.txt will automatically exclude building examples and tests when used as submodule, the configuration options now use a prefixed name to reduce risk of conflicts.ghcFilesystemConfig.cmake in ${CMAKE_INSTALL_LIBDIR}/cmake/ghcFilesystem for find_package that exports a target as ghcFilesystem::ghc_filesystem .error: redundant redeclaration of 'constexpr' static data member deprecation warning in C++17 mode.fs::create_directories , thanks for the PR!GHC_FILESYSTEM_WITH_INSTALL that is defaulted to OFF if ghc::filesystem is used via add_subdirectory .fs::path::lexically_normal() that leaves a trailing separator in case of a resulting path ending with .. as last element.BUILD_TESTING and BUILD_EXAMPLES to NO , OFF or FALSE .std::string_view when available was added.std::string_view is available.fs::path::preferred_separator declaration was not compiling on pre C++17 compilers and no test accessed it, to show the problem. Fixed it to an construction C++11 compiler should accept and added a test that is successful on all combinations tested.fs::copy_options where not forwarded from fs::copy to fs::copy_file in one of the cases.strerror_r signature was expected. The complex preprocessor define mix was dropped in favor of the usual dispatch by overloading a unifying wrapper.ghc::filesystem missed a <vector> include in the windows case.wchar_t/std::wstring interface when compiling on Windows with defined GHC_WIN_WSTRING_STRING_TYPE , this is default when using the ghc/fs_std*.hpp header, to enhance compatibility.GHC_RAISE_UNICODE_ERRORS (instead of replacing invalid code points or UTF-8 encoding errors with the replacement character U+FFFD ).fs::copy_file .readdir/readdir_r code of fs::directory_iterator ; as readdir_r is now deprecated, I decided to drop it and the resulting code is much easier, shorter and due to more refactoring fasterstd::filesystemfs::path::lexically_normal() had some issues with ".." -sequences.fs::recursive_directory_iterator could run into endless loops, the methods depth() and pop() had issues and the copy behavior and input_iterator_tag conformance was broken, added testsstd::filesystem builds of tests and examples for interoperability checks.fs::weakly_canonical() tests against std::fsdu example showing the recursive_directory_iterator used to add the sizes of files in a directory tree.fs::file_time_type test helpersfs::copy() now conforms LWG #2682, disallowing the use of `copy_option::create_symlinks' to be used on directorieshpp as extension to be marked as c++ and they where moved to include/ghc/ to be able to include by <ghc/filesystem.hpp> as the former include name might have been to generic and conflict with other files.ghc::filesystem now can be used as a submodul and added with add_subdirectory and will export itself as ghc_filesystem target. To use it, only target_link_libraries(your-target ghc_filesystem) is needed and the include directories will be set so #include <ghc/filesystem.hpp> will be a valid directive. Still you can simply only add the header file to you project and include it from there.ghc::filesystem declarations ( fs_fwd.hpp ) and to wrap the implementation into a single cpp ( fs_impl.hpp )std::basic_string_view variants of the fs::path api are now supported when compiling with C++17.ghc::filesystem::path::generic_string()filesystem.h was renamed filesystem.hpp to better reflect that it is a c++ language header.ghc::filesystem::remove() and ghc::filesystem::remove_all() both are now able to remove a single file and both will not raise an error if the path doesn't exist.ghc::filesystem::remove() under Windows.ghc::filesystem::directory_iterator now releases resources when reaching end() like the POSIX one does.ghc::filesystem::copy() and ghc::filesystem::remove_all fixed.ghc::filesystem::recursive_directory_iterator::difference_type .-Wall -Wextra -Werror and fixed resulting issues.fs.op.permissions test to work with all tested std::filesystem implementations (gcc, clang, msvc++).ghc::filesystem::u8arguments as argv converter, to help follow the UTF-8 path on windows. Simply instantiate it with argc and argv and it will fetch the Unicode version of the command line and convert it to UTF-8. The destructor reverts the change.examples folder with hopefully some usefull example usage. Examples are tested (and build) with ghc::filesystem and C++17 std::filesystem when available.std::filesystem for comparison.fstream include.timespec / timeval usage.chrono conversion issues in test and example on clang 7.0.0.ghc::filesystem::canonical now sees empty path as non-existant and reports an error. Due to this ghc::filesystem::weakly_canonical now returns relative paths for non-existant argument paths. (#1)ghc::filesystem::remove_all now also counts directories removed (#2)recursive_directory_iterator tests didn't respect equality domain issues and dereferencapable constraints, leading to fails on std::filesystem tests.noexcept tagged methods and functions could indirectly throw exceptions due to UFT-8 decoding issues.std_filesystem_test is now also generated if LLVM/clang 7.0.0 is found. This was the first public release version. It implements the full range of C++17 std::filesystem , as far as possible without other C++17 dependencies.