
ghc::filesystem::ifstream , ghc::filesystem::ofstream , ghc::filesystem::fstreamghc::filesystem::u8arguments Esta es una biblioteca de ayuda compatible con std::filesystem , basada en las especificaciones C ++ 17 y C ++ 20, pero implementadas para C ++ 11, C ++ 14, C ++ 17 o C ++ 20 (siguiendo el estándar C ++ 17 con muy pocas excepciones documentadas). Actualmente se prueba en 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 y Solaris 10, pero también deberían funcionar en otros sistemas, siempre que tenga al menos un compilador compatible C ++ 11. Debería funcionar con Android NDK, Emscripten y yo incluso tuvimos informes de que se usara en iOS (dentro de las limitaciones de sandboxing) y con V1.5.6 Existe un soporte experimental para QNX. El soporte de Android NDK, Emscripten, QNX, y desde 1.5.14 GNU/Hurd y Haiku no está respaldado por pruebas automatizadas, pero los informes de PRS y errores son bienvenidos para aquellos y se informa que funcionan. Por supuesto, se encuentra en su propio espacio de nombres ghc::filesystem no interferir con un std::filesystem si lo usa en un entorno mixto C ++ 17 (lo cual es posible).
La cobertura de prueba está muy por encima del 90%, y comenzando con V1.3.6 y en V1.5.0 se invirtió más tiempo en la evaluación comparativa y optimización de partes de la biblioteca. Intentaré continuar optimizando algunas piezas y refactorizar otras, esforzándose por mejorarlo siempre que no introduzca problemas adicionales de compatibilidad C ++ 17/C ++ 20. Los comentarios siempre son bienvenidos. Simplemente abra un problema si ve algo faltante o incorrecto o no se comporta como se esperaba y lo comentaré.
A menudo necesito la funcionalidad del sistema de archivos, principalmente fs::path , pero el acceso al directorio también, y al comenzar a usar C ++ 11, utilicé esa actualización de idioma para tratar de reducir mis dependencias de terceros. Podría dejar la mayor parte de lo que usé, pero aún así perdí algunas cosas que comencé a implementar para divertirse. Originalmente basé a estos ayudantes en mis propias convenciones de codificación y nombres. Cuando se finalizó C ++ 17, quería usar esa interfaz, pero tomó un tiempo para esforzarme para convertir mis clases.
La implementación se basa estrechamente en el Capítulo 30.10 del estándar C ++ 17 y un borrador cercano a esa versión está funcionando el borrador N4687. Es desde la estandarización de C ++ 17, pero contiene los últimos cambios de interfaz del sistema de archivos en comparación con el borrador de trabajo N4659. Mirando con V1.4.0, cuando se compila usando C ++ 20, se adapta a los cambios de acuerdo con el orden de clasificación de ruta y el manejo std::u8string del borrador de trabajo N4860.
Quiero agradecer a las personas que trabajan para mejorar C ++, realmente me gustó cómo evolucionó el lenguaje con C ++ 11 y los siguientes estándares. ¡Sigue con el buen trabajo!
Si te preguntas, qué está defendiendo ghc , son simplemente gulraks helper classes , sí, lo sé, no muy imaginativo, pero quería un espacio de nombres corto y lo uso en algunas de mis clases privadas (por lo que no tiene nada que ver con Haskell , perdón por el nombre del nombre).
ghc::filesystem se desarrolla en macOS pero CI probado en macOS, Windows, varias distribuciones de Linux, FreeBSD y comenzando con V1.5.12 en Solaris. Debería funcionar en cualquiera de estos con un compilador con capacidad de C ++ 11. También hay algunos cheques para trabajar mejor en Android, pero como actualmente no pruebo con el NDK de Android, todavía no lo llamaría una plataforma compatible, lo mismo es válido para usarlo con Emscripten. Ahora es parte de las plataformas detectadas, solucioné los problemas obvios y ejecuté algunas pruebas con él, por lo que debería estar bien. En general, no veo que reemplace std::filesystem donde está disponible C ++ 17 o C ++ 20 completo, no intenta ser un std::filesystem "mejor", solo un toque casi si no puede usarlo (con la excepción de la preferencia UTF-8).
IMPORTANTE: Esta implementación está siguiendo la filosofía "UTF-8 en todas partes" en que todas las instancias std::string se interpretarán de la misma manera que std::u8string codifica sabio y como en UTF-8. El std::u16string se verá como UTF-16. Ver diferencias en API para obtener más información.
Las pruebas unitarias se ejecutan actualmente con:
El encabezado viene con un conjunto de pruebas unitarias y utiliza CMake como herramienta de compilación y Catch2 como marco de prueba. Todas las pruebas están registradas en CMake, por lo que el comando CTEST se puede usar para ejecutar las pruebas.
Todas las pruebas contra esta implementación deberían tener éxito, dependiendo de su entorno, podría ser que haya algunas advertencias, por ejemplo, si no tiene derecho a crear enlaces simbólicos en Windows o al menos la prueba piensa que sí, pero estas son solo informativas.
Para construir las pruebas desde el interior del directorio del proyecto en MacOS o Linux solo:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
ctestEsto genera los binarios de prueba que ejecutan las pruebas y el último comando los ejecuta.
Si el compilador predeterminado es un GCC 8 o más nuevo, o CLANG 7 o más nuevo, también intenta construir una versión del binario de prueba compilado contra GCCS/Clangs std::filesystem Implementation, llamado std_filesystem_test como una prueba adicional de conformidad. Idealmente, todas las pruebas deberían compilar y tener éxito con todas las implementaciones del sistema de archivos, pero en realidad, existen algunas diferencias en el comportamiento, a veces debido al margen de interpretación en el estándar, y también podría haber problemas en estas implementaciones.
La última versión de lanzamiento es V1.5.14 y los archivos de origen se pueden encontrar aquí.
La última versión previa al backend es V1.4.0 y los archivos de origen se pueden encontrar aquí.
La última versión de lanzamiento de pre-C ++ 20 de soporte es V1.3.10 y los archivos de origen se pueden encontrar aquí.
Actualmente, solo la última versión de versión menor recibe correcciones de errores, por lo que si es posible, debe usar la última versión.
Como ghc::filesystem es al principio una biblioteca solo de encabezado, debe ser suficiente para copiar el encabezado o el directorio include/ghc en la carpeta de su proyecto o apuntar su ruta de inclusión a este lugar e simplemente incluir el encabezado filesystem.hpp (o ghc/filesystem.hpp si usa el subdirectorio).
Todo está en el espacio de nombres ghc::filesystem , por lo que una forma de usarlo solo como podría ser un respaldo:
# 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 Si también desea usar el envoltorio fstream con soporte path como Fallback, puede usar:
# 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 Ahora tienes, por ejemplo fs::ofstream out(somePath); Y es el envoltorio o el C ++ 17 std::ofstream .
Tenga en cuenta, como una biblioteca de solo encabezado, no oculta el hecho, que utiliza el sistema que incluye, por lo que "contaminan" su espacio de nombres global. Use el enfoque basado en el encabezado de reenvío/implementación (ver más abajo) para evitar esto. Para Windows, necesita Windows.h y podría ser una buena idea definir los encabezados WIN32_LEAN_AND_MEAN o NOMINMAX antes de incluir filesystem.hpp o fs_std.hpp encabezados para reducir la contaminación de su espacio de nombres global y tiempo de compilación. No están definidos por ghc::filesystem para permitir la combinación con contextos donde se necesita el Windows.h completo. H, por ejemplo, para elementos de UI.
Sugerencia: hay un encabezado adicional llamado ghc/fs_std.hpp que implementa esta selección dinámica de una implementación del sistema de archivos, que puede incluir en lugar de ghc/filesystem.hpp cuando desea std::filesystem donde está disponible y ghc::filesystem donde no.
Alternativamente, a partir de V1.1.0 ghc::filesystem también se puede usar al incluir uno de los dos encabezados de envoltura adicionales. Estos permiten incluir una versión reenviada en la mayoría de los lugares ( ghc/fs_fwd.hpp ) mientras oculta los detalles de implementación en un solo archivo CPP que incluye ghc/fs_impl.hpp para implementar el código necesario. Uso de ghc::filesystem de esta manera Asegúrese de que el sistema incluye solo visible desde el interior del archivo CPP, todos los demás lugares están limpios.
Tenga en cuenta que actualmente no es compatible para ocultar la implementación en un Windows-DLL, ya que una interfaz DLL con plantillas estándar C ++ en interfaces es una bestia diferente. Si alguien está dispuesto a intentarlo, podría integrar un relaciones públicas, pero actualmente trabajar en eso no es una prioridad.
Si utiliza el enfoque de reenvío/implementación, aún puede usar el cambio dinámico de esta manera:
# 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 Y en el CPP de Ocultación de implementación, puede usar (antes de que cualquiera incluya que incluya ghc/fs_fwd.hpp para tener prioridad:
# 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 Sugerencia: hay encabezados de ayuda adicionales, llamados ghc/fs_std_fwd.hpp y ghc/fs_std_impl.hpp que usan esta técnica, por lo que simplemente puede incluirlos si desea seleccionar dinámicamente la implementación del sistema de archivos.
A partir de V1.1.0, es posible agregar ghc::filesystem como un submódulo Git, agregue el directorio a su CMakeLists.txt con add_subdirectory() y luego simplemente use target_link_libraries(your-target ghc_filesystem) para garantizar que la ruta correcta que permita #include <ghc/filesystem.hpp> a Work.
CMakeLists.txt ofrece algunas opciones para personalizar su comportamiento:
GHC_FILESYSTEM_BUILD_TESTING - compilar pruebas, el valor predeterminado está OFF cuando se usa como submódulo, de lo ON .GHC_FILESYSTEM_BUILD_EXAMPLES : compile los ejemplos, el valor predeterminado está OFF cuando se usa como submódulo, de lo ON .GHC_FILESYSTEM_WITH_INSTALL : agregue el objetivo de instalación para construir, el valor predeterminado está OFF cuando se usa como un submódulo, de lo ON .GHC_FILESYSTEM_BUILD_STD_TESTING - compilar std_filesystem_test , la variante del conjunto de pruebas que se ejecuta contra std::filesystem , por defecto a GHC_FILESYSTEM_BUILD_TESTING . Esto solo se hace si se detecta el compilador como capaz de hacerlo.GHC_FILESYSTEM_TEST_COMPILE_FEATURES se puede establecer en una lista de características para anular CMAKE_CXX_COMPILE_FEATURES cuando la detección de C ++ 17 o C ++ 20 para pruebas adicionales no funciona (por ejemplo, cxx_std_20 para obtener la construcción de un filesystem_test_cpp20 con C ++ 20).Utilice HedronVision/Bazel-CC-Filesystem-Backport, que automáticamente configurará todo para usted.
Hay una versión macro GHC_FILESYSTEM_VERSION definida en caso de que los cambios futuros puedan reaccionar en la versión, pero no planeo romper nada. Es la versión como número decimal (major * 10000 + minor * 100 + patch) .
Nota: Solo se utilizarán versiones de parche incluso para lanzamientos y la versión de parche impar solo se utilizará entre compromisos mientras se trabaja en la próxima versión.
Casi no hay documentación en esta versión, ya que cualquier documentación std::filesystem funcionaría, además de las pocas diferencias explicadas en la siguiente sección. Por lo tanto, puede dirigirse a https://en.cppreference.com/w/cpp/filesystem para obtener una descripción de los componentes de esta biblioteca.
Al compilar con C ++ 11, C ++ 14 o C ++ 17, la API sigue el estándar C ++ 17, cuando sea posible, con la excepción de que los parámetros std::string_view solo son compatibles con C ++ 17. Al compilar con C ++ 20, ghc::filesysytem predeterminado a la API C ++ 20, con las interfaces char8_t y std::u8string y el método de fábrica fs::u8path Depreced.
Nota: Si la API C ++ 17 debe aplicarse incluso en el modo C ++ 20, use el GHC_FILESYSTEM_ENFORCE_CPP17_API . Incluso entonces, es posible crear fws::path desde std::u8string pero fs::path::u8string() y fs::path::generic_u8string() return Utf-8 Coded std::string Instities, por lo que el código escrito para C ++ 17 todavía podría funcionar con ghc::filesystem cuando se compiló con C ++ 20. 20.
Las únicas adiciones al estándar se documentan aquí:
ghc::filesystem::ifstream , ghc::filesystem::ofstream , ghc::filesystem::fstream Estos son envoltorios simples alrededor de std::ifstream , std::ofstream y std::fstream . Simplemente agregan un método open() y un constructor con un argumento ghc::filesystem::path como las variantes fstream en C ++ 17 las tienen.
ghc::filesystem::u8argumentsEsta es una clase de ayuda que actualmente verifica la codificación UTF-8 en las plataformas no Windows, pero en Windows obtiene los argumentos de la línea de comandos como cadenas unicode desde el sistema operativo con
::CommandLineToArgvW (::GetCommandLineW(), &argc) y luego los convierte a UTF-8 y reemplaza argc y argv . Es una clase similar a la guardia que revierte sus cambios al salir de alcance.
Entonces el uso básico es:
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 ;
} De esa forma, argv está codificado por UTF-8 siempre que el alcance de main sea válido.
Nota: En MacOS, mientras se depuración en Xcode, el código actualmente devolverá false ya que Xcode inicia la aplicación con US-ASCII como codificación, sin importar qué codificación se use realmente e incluso configurar LC_ALL en el esquema de producto no cambia nada. Todavía necesito investigar esto.
Como esta implementación se basa en el código existente de mis clases de ayudantes privados, obtuvo algunas limitaciones. A partir de V1.5.0, la mayoría de las diferencias entre este y la API estándar C ++ 17/C ++ 20 20 donde se elimina.
Esta implementación tiene un comportamiento conmutable para los defectos de LWG #2682, #2935, #2936 y #2937. El comportamiento seleccionado actualmente (a partir de V1.4.0) es el siguiente #2682, #2936, #2937 pero no siguiendo # fs::is_directory , ya que creo que es un error informar ningún error en un create_directory() o create_directories() donde un archivo regular del mismo nombre prohíbe la creación de un directorio y obliga a los usuarios de esas funciones a dos compensaciones a dos verificaciones. El enfoque más intuitivo para la creación del directorio de tratar un archivo con ese nombre como error también es recomendado por el nuevo documento WG21 P1164R0, la revisión P1161R1 fue acordada en la reunión de Kona 2019, ver Merge y GCC por ahora cambió a seguir su propuesta (GCC #86910).
// methods in ghc::filesystem::path:
path& operator +=(basic_string_view<value_type> x);
int compare (basic_string_view<value_type> s) const ; Estos no se implementan en C ++ 11 y C ++ 14, ya que no hay std::basic_string_view disponible y quería mantener esta implementación autónoma y no escribir una actualización completa de C ++ 17 para C ++ 11/14. Comenzando con V1.1.0, se admiten al compilar ghc::filesystem en C ++ 17 de C ++ 20.
Comenzando con V1.5.2 ghc::filesystem intentará permitir el uso de std::experimental::basic_string_view donde detecta la disponibilidad. Además, si tiene una implementación basic_string_view compatible de C ++ 11, se puede usar en lugar de std::basic_string_view definiendo GHC_HAS_CUSTOM_STRING_VIEW e importando la implementación en el espacio de nombres ghc::filesystem con:
namespace ghc {
namespace filesystem {
using my::basic_string_view;
}
}Antes de incluir el encabezado del sistema de archivos.
Para no depender de ninguna biblioteca externa de terceros y seguir siendo portátiles y compactos, esta implementación está siguiendo la filosofía "UTF-8 en todas partes" en que todas las instancias std::string se interpretarán de la misma manera que las codificaciones std::u8string sabia y como en UTF-8. El std::u16string se verá como UTF-16 y std::u32string se verá como puntos de código Unicode. Dependiendo del tamaño de los caracteres std::wstring , se encargará de std::wstring como UTF-16 (por ejemplo, Windows) o CodePoints de unicode char32_t (actualmente todas las demás plataformas).
Comenzando con V1.5.0 ghc::filesystem está siguiendo el estándar C ++ 17 en el uso de wchar_t y std::wstring en Windows como los tipos utilizados internamente para la representación de ruta. Todavía es posible obtener el antiguo comportamiento definiendo GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE y obtenga filesystem::path::string_type como std::string y filesystem::path::value_type como wchar_t .
Si necesita llamar a algunas API de Windows, con V1.5.0 y superior, simplemente use el W-Variant de la llamada Windows-API (por ejemplo, GetFileAttributesW(p.c_str()) ).
Nota: Al usar el comportamiento antiguo definiendo GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE , use la path::wstring() miembro (por ejemplo, GetFileAttributesW(p.wstring().c_str()) ). Esto le brinda la variante Unicode independiente de la macro UNICODE y facilita el código de intercambio entre Windows, Linux y MacOS y funciona con std::filesystem y 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 ; El tipo de retorno de estos dos métodos depende del estándar C ++ usado y si se define GHC_FILESYSTEM_ENFORCE_CPP17_API . En C ++ 11, C ++ 14 y C ++ 17 o cuando se define GHC_FILESYSTEM_ENFORCE_CPP17_API , el tipo de retorno es std::string , y en c ++ 20 sin la define es std::u8string .
Creé una entrada wiki sobre muchas diferencias de comportamiento entre diferentes implementaciones std::filesystem que podrían resultar en una mención aquí, pero este ReadMe solo trata de abordar las diferencias de elección de diseño entre ghc::filesystem Intento actualizar la página wiki de vez en cuando.
¡Cualquier observación adicional es bienvenida!
Desde V1.5.0, la mecánica interna completa de estas implementaciones fs::path donde cambió al formato nativo como la representación interna. Creación de cualquier objeto fs::path en Windows (por ejemplo, con "C:foo/bar" ) conducirá una ruta limpia con "C:foobar" a través de native() y "C:/foo/bar" a través de la API generic_string() . En todas las plataformas, se eliminan los separadores adicionales redundantes, incluso si esto no se aplica por el estándar y otras implementaciones en su mayoría no lo hacen.
Además, esta implementación sigue la sugerencia de estándares para manejar las rutas POSIX de la forma "//host/path" y la ruta USC en Windows también tiene un nombre de raíz (por ejemplo, "//host" ). La implementación de GCC no eligió hacer eso mientras se probaba en Ubuntu 18.04 y MacOS con GCC 8.1.0 o Clang 7.0.0. Esta diferencia se mostrará como advertencias en std::filesystem . This leads to a change in the algorithm described in the standard for operator/=(path& p) where any path p with p.is_absolute() will degrade to an assignment, while this implementation has the exception where *this == *this.root_name() and p == preferred_separator a normal append will be done, to allow:
fs::path p1 = " //host/foo/bar/file.txt " ;
fs::path p2;
for ( auto p : p1) p2 /= p;
ASSERT (p1 == p2);Para todas las rutas no líderes del host, el comportamiento coincidirá con el descrito por el estándar.
Como enlaces simbólicos en Windows, mientras se admiten más o menos ya que Windows Vista (con algunas limitaciones de seguridad estrictas) y totalmente, ya que algunas construcciones anteriores de Windows 10, cuando se activa el "modo de desarrollador", se activa al momento de escribir (2018), rara vez se usan, aún se les admite con esta implementación.
La función de permiso de ACL de Windows se traduce mal en la máscara de bits Posix Permission utilizada en la interfaz del sistema de archivos C ++ 17. Por lo tanto, los permisos devueltos en el file_status se sintetizan actualmente para el nivel user y se copian en el group y other niveles. Todavía existe un potencial para más interacción con el sistema de permiso de Windows, pero actualmente la configuración o los permisos de lectura con esta implementación ciertamente no conducirán al comportamiento esperado.
extension() devolvió el resultado no vacío para el nombre del directorio ".."ghcFilesystem::ghc_filesystem ahora se establece incondicionalmentestem() , filename() y extension() de fs::path devolvería el resultado incorrecto si un colon estuviera en el nombre de archivofs::last_write_time(path, time, ec) Setter en iOS, tvos y watchosfs::directory_entry::refresh() Ahora, consistentemente con status() no arrojará enlaces simbólicos a objetivos inexistentes, pero haga que la entrada tenga file_type::not_found como el tipoEINTR en la iteración del directorio POSIX y la copia del archivo para evitar errores en los sistemas de archivos de redfs::copy_file() Ahora también copia los permisosfs::copy_file() Ignorando la opción skip_existing .GHC_NO_DIRENT_D_TYPE en sistemas que no admiten dirent::d_type y la configuración de compilación fija y las pruebas para admitir Solaris como una nueva plataforma.PATH_MAX , uno está definido.fs::remove_all ahora solo elimina los enlaces simbólicos en lugar de seguirlos.fs::space donde podría ocurrir un desbordamiento numérico en una multiplicación.fs::create_directories en Windows ya no se rompe en nombres de archivo largos.ghc::filesystem Trated Montada Carpeta/volúmenes erróneamente como enlaces simbólicos, liderando fs::canonical Fail en rutas que contienen.recursive_directory_iterator no intentará ingresar a los enlaces simbólicos muertos.fs::remove falló cuando la ruta apuntó a una entrada de solo lectura, vea también (Microsoft/STL #1511) para el problema correspondiente en std::fs en Windows.GHC_NO_DIRENT_D_TYPE INTERNO Permite la detección del sistema operativo que admite sistemas sin el miembro dirent.d_type , el primer consultorio de la compilación QNX experimental como caso de uso inicial, un problema solucionado con los sistemas de archivos que devuelven dt_unknown (eg reiserfs).string_view cuando se detecta Clang con LibStdc ++.<Availability.h> se incluyó antes de <ghc/fs_std.hpp> o <ghc/fs_std_fwd.hpp> / <ghc/fs_std_impl.hpp> .std::filesystem son compatibles con los nombres de capítulos tipo etiqueta que permanecen (en su mayoría) consistentes sobre las versiones.recursive_directory_iterator sobre árboles grandes ahora en algún lugar entre libc ++ y libstdc ++.ghc::filesystem ahora tiene soporte preliminar para Cygwin. Cambios donde se realizan para permitir que las pruebas se compilen y se ejecuten con éxito (probado con GCC 10.2.0), los comentarios y los PR adicionales bienvenidos, ya que actualmente no forma parte de la configuración de CI.GHC_FILESYSTEM_BUILD_STD_TESTING para anular la compilación adicional de las versiones de std::filesystem de las pruebas para la comparación y la posibilidad de usar GHC_FILESYSTEM_TEST_COMPILE_FEATURES para prefirar las características del compile usados predeterminados en CMAKE_CXX_COMPILE_FEATURES cuando no se dan.directory_entry conduce a aproximadamente 20% -25% en pruebas con recursive_directory_iterator sobre un árbol de directorio más grande.wchar_t no estaba en la lista de tipos de char con los backends no windows.string_view utiliza <string_view> o <experimental/string_view> cuando esté disponible, y permite el uso de la implementación personalizada basic_string_view al definir GHC_HAS_CUSTOM_STRING_VIEW e importar la vista de cadena en el espacio de nombres ghc::filesystem antes de incluir el año del sistema de archivos.std::filesystem Tests ahora se enlaza con -lrt para evitar problemas.fs::hard_link_count falló debido al comportamiento de los sistemas de archivos, el caso de prueba se adaptó para tenerlo en cuenta.GHC_FS_API y GHC_FS_API_CLASS ahora se honra cuando se establece desde afuera para permitir la anulación de comportamiento.make install .GHC_FILESYSTEM_BUILD_TESTING , GHC_FILESYSTEM_BUILD_EXAMPLES y GHC_FILESYSTEM_WITH_INSTALL DONDE implementado, prohibido configurarlos de un proyecto principal cuando se usa esto a través de add_subdirectory , esta fianza permite establecerlos nuevamente.fs::path se creó originalmente a partir de la implementación basada en POSIX fue, mediante la adaptación de las cuerdas entrantes y salientes. Esto dio como resultado un caché mutable dentro de fs::path en las ventanas, que inherentemente no era segura de hilo, incluso para los métodos const . Para no agregar parches adicionales a una solución subóptima, esta vez reelaboré el código de path para ahora almacenar la representación de ruta nativa . Esto cambió mucho código, pero cuando se combinó con wchar_t como value_type ayudó a evitar mucha conversión para las llamadas a Win-API.fs::path::native() y fs::path::c_str() ahora puede ser noexcept como los mandatos estándarwchar_t ahora es el valor predeterminado para fs::path::value_type y std::wstring es el valor predeterminado para fs::path::string_type .const de fs::path ya no es un problemaGHC_WIN_DISABLE_AUTO_PREFIXES , para todos los demás tipos de prefijos o espacios de nombres, el comportamiento sigue el de msvc std::filesystem::pathchar / std::string con Windows, se puede activar con GHC_WIN_DISABLE_WSTRING_STORAGE_TYPEfs::file_status ahora admite operator== Introducido en std::filesystem con C ++ 20.fs::path::parent_path() tenía un problema de rendimiento, ya que todavía estaba utilizando un enfoque basado en bucle para recrear al padre de los elementos. Esto creó muchos temporales y era demasiado lento, especialmente en caminos largos.char8_t y std::u8string son compatibles donde Source es el tipo de parámetrofs::path::u8string() y fs::path::generic_u8string() Ahora devuelva un std::u8string<=> ahora es compatible con fs::pathGHC_FILESYSTEM_ENFORCE_CPP17_API ghc::filesystem volverá a la antigua fs::path::u8string() y fs::path::generic_u8string() si se prefierefs::proximate(p, ec) donde la llamada interna a fs::current_path() no estaba utilizando la variante error_code , lanzando posibles excepciones en lugar de configurar ec .LWG_2936_BEHAVIOUR ahora está activado de forma predeterminada.Source que son vistas de cadena.constexpr .__MAC_OS_X_VERSION_MIN_REQUIRED para garantizar que std::filesystem solo se seleccione en macOS si el objetivo de implementación es al menos catalina.directory_iterator y recursive_directory_iterator tuvieron un problema con la opción skip_permission_denied , que lleva a la incapacidad de omitir carpetas protegidas por SIP en macOS._MSVC_LANG ahora se usa cuando está disponible, además de __cplusplus , en los encabezados de ayuda para permitirles funcionar incluso cuando /Zc:__cplusplus no se usa.false en fs::exists o errores no encontrados en fs::status . Las rutas con espacio para nombres ya no se filtran.TestAllocator en filesystem_test.cpp se completó para cumplir con los requisitos para construir en CentOS 7 con devtoolset-9 . CentOS 7 y CentOS 8 ahora son parte de las construcciones de CI.LWG_2936_BEHAVIOUR que permite habilitar post c ++ 17 fs::path::compare , donde la comparación es como si fuera una comparación de ruta sabia de elementos como se describe en LWG 2936 y C ++ 20 [fs.path.compare] . Está desactivado en V1.3.6 y será predeterminado a partir de V1.4.0 a medida que cambia el pedido.wchar_t de std::fstream desde ghc::filesystem::fstream wrappers en Windows si usa GCC con libc ++.fs::directory_options::skip_permission_denied y soporte inicial para la compilación con Emscripten.ghc::filesystem ahora admite el uso en proyectos con excepciones deshabilitadas. Las firmas de API que usan excepciones para el manejo de errores no están disponibles en este modo, gracias por el PR (esto resuelve el #60 y el #43)ERROR_FILE_TOO_LARGE constante.fs::lexically_relative No ignoró la barra de arrastre en el parámetro base, gracias por PR #57.fs::create_directories devolvió true cuando no es necesario crear nada, porque el directorio ya existía.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.