
ghc::filesystem::ifstream , ghc::filesystem::ofstream , ghc::filesystem::fstreamghc::filesystem::u8arguments Esta é uma biblioteca auxiliar compatível com o std::filesystem apenas cabeçalho, com base nas especificações C ++ 17 e C ++ 20, mas implementada para C ++ 11, C ++ 14, C ++ 17 ou C ++ 20 (seguindo firmemente o padrão C ++ 17, com muito poucas exceções documentadas). Atualmente, é testado no 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 e Solaris 10, mas deve funcionar em outros sistemas, também, pelo menos, pelo menos um C ++ 11 11. Ele deve funcionar com o Android NDK, EMSCRIPTEN e eu até tínhamos relatos de que ele foi usado no iOS (dentro de restrições de sandbox) e com v1.5.6 Há suporte experimental para QNX. O apoio do Android NDK, EMSCRIPTEN, QNX e desde 1.5.14 GNU/Hurd e Haiku não é apoiado por testes automatizados, mas os relatórios de PRs e bugs também são bem -vindos e eles são relatados para funcionar. É claro que está em seu próprio espaço de nome ghc::filesystem para não interferir em um sistema de arquivos std::filesystem , caso você o use em um ambiente misto C ++ 17 (o que é possível).
A cobertura do teste está bem acima de 90%e, a partir da v1.3.6 e na v1.5.0, mais tempo foi investido em benchmarking e otimizar partes da biblioteca. Vou tentar continuar a otimizar algumas peças e refatorar outras, esforçando -se para melhorá -la, desde que não introduza problemas adicionais de compatibilidade C ++ 17/C ++ 20. O feedback é sempre bem -vindo. Basta abrir um problema se você vir algo ausente ou errado ou não se comportar como o esperado e eu comentarei.
Muitas vezes, preciso da funcionalidade do sistema de arquivos, principalmente fs::path , mas também acesso ao diretório e, ao começar a usar o C ++ 11, usei essa atualização de idioma para tentar reduzir minhas dependências de terceiros. Eu poderia abandonar a maior parte do que usei, mas ainda perdi algumas coisas que comecei a implementar por diversão. Originalmente, baseei esses ajudantes em minhas próprias convenções de codificação e nomeação. Quando o C ++ 17 foi finalizado, eu queria usar essa interface, mas demorou um pouco, para me esforçar para converter minhas aulas.
A implementação é baseada de perto no capítulo 30.10 do padrão C ++ 17 e um rascunho próximo a essa versão está funcionando N4687. É de após a padronização do C ++ 17, mas contém as mais recentes mudanças na interface do sistema de arquivos em comparação com o rascunho de trabalho N4659. Olhando com a v1.4.0, quando compilado usando C ++ 20, ele se adapta às alterações de acordo com a ordem de classificação do caminho e std::u8string manuseio do N4860 de trabalho.
Quero agradecer às pessoas que trabalham para melhorar o C ++, gostei muito de como o idioma evoluiu com C ++ 11 e os seguintes padrões. Continue no bom trabalho!
Se você se perguntar, o que ghc está defendendo, são simplesmente gulraks helper classes , sim, eu sei, não é muito imaginativo, mas eu queria um espaço de nome de nome curto e o uso em algumas das minhas aulas particulares (por isso não tem nada a ver com Haskell , desculpe o nome do nome).
ghc::filesystem é desenvolvido no macOS, mas o CI testado no macOS, Windows, várias distribuições Linux, FreeBSD e começando com v1.5.12 no Solaris. Deve funcionar em qualquer um deles com um compilador C ++ 11 compilador. Além disso, existem alguns cheques para trabalhar melhor no Android, mas, como atualmente não testo com o Android NDK, eu não chamaria de plataforma suportada, mas o mesmo é válido para usá -lo com o EMSCRIPTEN. Agora faz parte das plataformas detectadas, corrigi os problemas óbvios e executei alguns testes com ele, por isso deve ficar bem. Em suma, não vejo isso substituindo std::filesystem onde está disponível C ++ 17 ou C ++ 20, ele não tenta ser um "melhor" std::filesystem , apenas uma queda se você não puder usá-lo (com exceção da preferência do UTF-8).
IMPORTANTE: Esta implementação está seguindo a filosofia "UTF-8 em todos os lugares", pois todas as instâncias std::string serão interpretadas da mesma forma que std::u8string que codifica o Wise e como estando no UTF-8. O std::u16string será visto como UTF-16. Veja as diferenças na API para obter mais informações.
Os testes de unidade estão atualmente executados com:
O cabeçalho vem com um conjunto de testes de unidade e usa o CMake como uma ferramenta de construção e o Catch2 como estrutura de teste. Todos os testes são registrados no CMake, para que o comando CTEST possa ser usado para executar os testes.
Todos os testes contra essa implementação devem ter sucesso, dependendo do seu ambiente, pode ser que haja alguns avisos, por exemplo, se você não tiver direitos para criar links simbólicos no Windows ou pelo menos o teste pensa assim, mas esses são apenas informativos.
Para construir os testes de dentro do diretório do projeto em MacOS ou Linux apenas:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
ctestIsso gera os binários de teste que executam os testes e o último comando os executa.
Se o compilador padrão for um GCC 8 ou mais recente, ou Clang 7 ou mais recente, ele também tentará criar uma versão do binário de teste compilado contra a implementação std::filesystem , denominada std_filesystem_test como um teste adicional de conforto. Idealmente, todos os testes devem compilar e ter sucesso com todas as implementações do sistema de arquivos, mas, na realidade, existem algumas diferenças de comportamento, às vezes devido ao espaço para interpretação no padrão, e também pode haver problemas nessas implementações.
A versão mais recente de lançamento é v1.5.14 e os arquivos de origem podem ser encontrados aqui.
A mais recente versão pré-nativa é a v1.4.0 e os arquivos de origem podem ser encontrados aqui.
A versão mais recente de liberação pré-C ++ 20-Support é a v1.3.10 e os arquivos de origem podem ser encontrados aqui.
Atualmente, apenas a versão mais recente de lançamento menor recebe bugs, por isso, se possível, você deve usar a versão mais recente.
Como ghc::filesystem é inicialmente uma biblioteca somente para cabeçalho, deve ser suficiente para copiar o cabeçalho ou o diretório include/ghc na pasta do projeto ou apontar o caminho de incluir para este local e simplesmente incluir o cabeçalho filesystem.hpp (ou ghc/filesystem.hpp se você usar o subdiretório).
Tudo está no espaço de nome ghc::filesystem , então uma maneira de usá -lo apenas como um fallback poderia ser:
# 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 Se você também deseja usar o invólucro fstream com suporte path como fallback, você pode 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 Agora você tem, por exemplo fs::ofstream out(somePath); E é o invólucro ou o C ++ 17 std::ofstream .
Esteja ciente, como uma biblioteca somente para cabeçalho, não está escondendo o fato de que ele usa o sistema inclui, para que eles "poluem" o seu espaço de nome global. Use a abordagem baseada em encaminhamento/implementação (veja abaixo) para evitar isso. Para o Windows, ele precisa Windows.h e pode ser uma boa idéia definir WIN32_LEAN_AND_MEAN ou NOMINMAX ANTES DE INCLUIR filesystem.hpp ou fs_std.hpp Cabeçalhos para reduzir a poluição do seu espaço de nome global e o tempo de compilação. Eles não são definidos pelo ghc::filesystem para permitir combinação com contextos em que o Windows.h completo é necessário, por exemplo, para elementos da interface do usuário.
Dica: existe um cabeçalho adicional chamado ghc/fs_std.hpp que implementa essa seleção dinâmica de uma implementação do sistema de arquivos, que você pode incluir em vez de ghc/filesystem.hpp quando você deseja std::filesystem onde disponível e ghc::filesystem onde não.
Como alternativa, a partir da v1.1.0 ghc::filesystem também pode ser usado incluindo um dos dois cabeçalhos de wrapper adicionais. Isso permite incluir uma versão encaminhada na maioria dos lugares ( ghc/fs_fwd.hpp ) enquanto oculta os detalhes da implementação em um único arquivo CPP que inclui ghc/fs_impl.hpp para implementar o código necessário. Usando ghc::filesystem dessa maneira garante que o sistema inclua apenas a partir de dentro do arquivo CPP, todos os outros lugares estão limpos.
Esteja ciente de que atualmente não é suportado para ocultar a implementação em uma interface do Windows, como uma interface DLL com modelos padrão C ++ nas interfaces é um animal diferente. Se alguém estiver disposto a tentar, posso integrar um PR, mas atualmente trabalhando nisso não é uma prioridade.
Se você usar a abordagem de encaminhamento/implementação, ainda poderá usar a comutação dinâmica assim:
# 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 E na implementação que oculta o CPP, você pode usar (antes de qualquer inclusão que inclua ghc/fs_fwd.hpp para ter precedência:
# 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 Dica: existem cabeçalhos auxiliares adicionais, denominados ghc/fs_std_fwd.hpp e ghc/fs_std_impl.hpp que usam essa técnica, para que você possa incluí -los se deseja selecionar dinamicamente a implementação do sistema de arquivos.
A partir da v1.1.0, é possível adicionar ghc::filesystem como um submódulo Git, adicione o diretório aos seus CMakeLists.txt com add_subdirectory() e, em seguida, basta usar target_link_libraries(your-target ghc_filesystem) para garantir o caminho correto que permita o caminho #include <ghc/filesystem.hpp> .
O CMakeLists.txt oferece algumas opções para personalizar seu comportamento:
GHC_FILESYSTEM_BUILD_TESTING - testes de compilação, o padrão é OFF quando usado como submodule, ON .GHC_FILESYSTEM_BUILD_EXAMPLES - compilar os exemplos, o padrão é OFF quando usado como submodule, caso ON .GHC_FILESYSTEM_WITH_INSTALL - adicione o destino de instalação para construir, o padrão é OFF quando usado como submodule, caso ON .GHC_FILESYSTEM_BUILD_STD_TESTING - compile std_filesystem_test , a variante do conjunto de testes em execução contra std::filesystem , inadimplente para GHC_FILESYSTEM_BUILD_TESTING . Isso só é feito se o compilador for detectado como capaz de fazê -lo.GHC_FILESYSTEM_TEST_COMPILE_FEATURES pode ser definido como uma lista de recursos para substituir CMAKE_CXX_COMPILE_FEATURES quando a detecção de C ++ 17 ou C ++ 20 para testes adicionais não está funcionando (por exemplo, cxx_std_20 para a construção de filesystem_test_cpp20 .Use Hedronvision/Bazel-CC-Filesystem-Backport, que configurará automaticamente tudo para você.
Existe uma versão macro GHC_FILESYSTEM_VERSION definida caso as mudanças futuras possam tornar necessárias para reagir na versão, mas não pretendo quebrar nada. É a versão como número decimal (major * 10000 + minor * 100 + patch) .
NOTA: Somente até as versões de patches serão usadas para lançamentos e a versão ímpar de patches será usada apenas entre as confirmações enquanto trabalha na próxima versão.
Quase não há documentação nesta versão, pois qualquer documentação std::filesystem funcionaria, além das poucas diferenças explicadas na próxima seção. Portanto, você pode ir para https://en.cppreference.com/w/cpp/filesystem para obter uma descrição dos componentes desta biblioteca.
Ao compilar com C ++ 11, C ++ 14 ou C ++ 17, a API está seguindo o padrão C ++ 17, sempre que possível, com a exceção de que os parâmetros std::string_view são suportados apenas em C ++ 17. Ao compilar com C ++ 20, ghc::filesysytem é o padrão da API C ++ 20, com as interfaces char8_t e std::u8string e o método fs::u8path Factory.
NOTA: Se a API C ++ 17 deverá ser aplicada mesmo no modo C ++ 20, use o define GHC_FILESYSTEM_ENFORCE_CPP17_API . Mesmo assim, é possível criar fws::path a partir de std::u8string , mas fs::path::u8string() e fs::path::generic_u8string() Retornar UTF-8 normal codificado std::string Instâncias, então o código escrito para C ++ 17 ainda pode trabalhar com ghc::filesystem
As únicas adições ao padrão estão documentadas aqui:
ghc::filesystem::ifstream , ghc::filesystem::ofstream , ghc::filesystem::fstream Estes são invólucros simples em torno de std::ifstream , std::ofstream e std::fstream . Eles simplesmente adicionam um método open() e um construtor com um argumento ghc::filesystem::path como as variantes fstream em C ++ 17 os têm.
ghc::filesystem::u8argumentsEsta é uma classe auxiliar que atualmente verifica a codificação do UTF-8 em plataformas que não são de janelas, mas no Windows ele busca os argumentos da linha de comando como strings unicode do sistema operacional
::CommandLineToArgvW (::GetCommandLineW(), &argc) e depois os converte em UTF-8 e substitui argc e argv . É uma classe de guarda que reverte suas mudanças ao sair do escopo.
Portanto, o uso básico é:
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 ;
} Dessa forma, argv é o UTF-8 codificado enquanto o escopo do main for válido.
Nota: no macOS, enquanto a depuração do Xcode, o código atualmente retornará false , pois o Xcode inicia o aplicativo com US-ASCII como codificação, independentemente do que a codificação é realmente usada e até definir LC_ALL no esquema de produtos não muda nada. Eu ainda preciso investigar isso.
Como essa implementação é baseada no código existente das minhas classes de auxiliar privado, ele derivou algumas restrições dele. A partir da v1.5.0, a maioria das diferenças entre isso e a API padrão C ++ 17/C ++ 20 quando foi removida.
Essa implementação tem um comportamento comutável para os defeitos LWG #2682, #2935, #2936 e #2937. O comportamento atualmente selecionado (a partir da v1.4.0) está seguindo o #2682, #2936, #2937, mas não seguindo o #2935, pois sinto que é um bug relatar nenhum erro em um create_directory() ou create_directories() onde um arquivo regular do mesmo nome proíbe a criação de fs::is_directory trabalhado. A abordagem mais intuitiva para a criação do diretório de tratar um arquivo com esse nome como um erro também é defendida pelo artigo mais recente WG21 P1164R0, a revisão P1161R1 foi acordada na reunião do KONA 2019, consulte Merge e GCC até agora mudou para a seguinte proposta (GCC #86910).
// methods in ghc::filesystem::path:
path& operator +=(basic_string_view<value_type> x);
int compare (basic_string_view<value_type> s) const ; Eles não são implementados em C ++ 11 e C ++ 14, pois não há std::basic_string_view disponível e eu queria manter essa implementação independente e não escrever um upgrade C ++ 17 completo para C ++ 11/14. Começando com v1.1.0 estes são suportados ao compilar ghc::filesystem em C ++ 17 de C ++ 20.
Começando com v1.5.2 ghc::filesystem tentará permitir o uso de std::experimental::basic_string_view onde detecta a disponibilidade. Além disso, se você tiver uma implementação basic_string_view Compatible C ++ 11, ele pode ser usado em vez de std::basic_string_view , definindo GHC_HAS_CUSTOM_STRING_VIEW e importando a implementação para o namespace ghc::filesystem com:
namespace ghc {
namespace filesystem {
using my::basic_string_view;
}
}Antes de incluir o cabeçalho do sistema de arquivos.
Para não depender de nenhuma biblioteca externa de terceiros e ainda permanecer portátil e compacto, essa implementação está seguindo a filosofia "UTF-8 em todos os lugares", na medida em que todas as instâncias std::string serão interpretadas da mesma forma que a codificação std::u8string codificando e como estando no UTF-8. O std::u16string será visto como UTF-16 e std::u32string será visto como pontos de código Unicode. Dependendo do tamanho dos caracteres std::wstring , ele lidará com std::wstring como sendo UTF-16 (por exemplo, Windows) ou char32_t Unicode CodePoints (atualmente todas as outras plataformas).
Começando com v1.5.0 ghc::filesystem está seguindo o padrão C ++ 17 ao usar wchar_t e std::wstring no Windows como os tipos usados internamente para representação do caminho. Ainda é possível obter o comportamento antigo definindo GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE e Get filesystem::path::string_type como std::string e filesystem::path::value_type como wchar_t .
Se você precisar ligar para algumas API do Windows, com v1.5.0 e acima, basta usar o W-Variant da chamada Windows-API (por exemplo, GetFileAttributesW(p.c_str()) ).
Nota: Ao usar o comportamento antigo definindo GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE , use o membro do path::wstring() (por exemplo, GetFileAttributesW(p.wstring().c_str()) ). Isso fornece a variante Unicode independente da macro UNICODE e facilita o compartilhamento de código entre Windows, Linux e MacOS e funciona com std::filesystem e 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 ; O tipo de retorno desses dois métodos depende do padrão C ++ usado e se GHC_FILESYSTEM_ENFORCE_CPP17_API for definido. Em C ++ 11, C ++ 14 e C ++ 17 ou quando GHC_FILESYSTEM_ENFORCE_CPP17_API é definido, o tipo de retorno é std::string e no C ++ 20 sem a definição, é std::u8string .
Criei uma entrada do Wiki sobre muitas diferenças comportamentais entre diferentes implementações de std::filesystem que podem resultar em uma menção aqui, mas isso só tenta abordar as diferenças de escolha de design entre ghc::filesystem e esses. Eu tento atualizar a página do Wiki de tempos em tempos.
Quaisquer observações adicionais são bem -vindas!
Desde v1.5.0, a mecânica interna completa dessas implementações fs::path foi alterado para o formato nativo como representação interna. Criar qualquer objeto Mixed Slash fs::path em Windows (por exemplo, com "C:foo/bar" ) liderará o caminho limpo com "C:foobar" via native() e "C:/foo/bar" via API generic_string() . Em todas as plataformas, separadores adicionais redundantes são removidos, mesmo que isso não seja aplicado pelo padrão e outras implementações, principalmente não fazem isso.
Além disso, essa implementação segue a sugestão de padrões para lidar com os caminhos POSIX do formulário "//host/path" e o caminho da USC no Windows também como tendo um nome de raiz (por exemplo "//host" ). A implementação do GCC não optou por fazer isso ao testar no Ubuntu 18.04 e no MacOS com o GCC 8.1.0 ou CLANG 7.0.0. Essa diferença será exibida como avisos sob std::filesystem . Isso leva a uma mudança no algoritmo descrito no padrão para operator/=(path& p) onde qualquer caminho p com p.is_absolute() se degradará a uma tarefa, enquanto essa implementação tem a exceção em que *this == *this.root_name() e p == preferred_separator um apêndice normal será feito, para permitir:
fs::path p1 = " //host/foo/bar/file.txt " ;
fs::path p2;
for ( auto p : p1) p2 /= p;
ASSERT (p1 == p2);Para todos os caminhos que não são líderes, o comportamento corresponderá ao descrito pelo padrão.
Como links simbólicos no Windows, sendo suportados mais ou menos desde o Windows Vista (com algumas restrições estritas de segurança) e completamente desde que alguma construção anterior do Windows 10, quando o "modo de desenvolvedor" é ativado, no momento da redação (2018) raramente usadas, ainda são suportadas com essa implementação.
O recurso de permissão do Windows ACL se traduz mal com a máscara de bits de permissão POSIX usada na interface do sistema de arquivos C ++ 17. As permissões retornadas no file_status são, portanto, atualmente sintetizadas para o nível user e copiadas para o group -e other nível. Ainda existe algum potencial para mais interação com o sistema de permissão do Windows, mas atualmente definir ou ler permissões com essa implementação certamente não levará ao comportamento esperado.
extension() retornou resultado não vazio para o nome do diretório ".."ghcFilesystem::ghc_filesystem agora está definido incondicionalmentestem() , filename() e extension() de fs::path retornaria o resultado errado se um cólon estivesse no nome do arquivofs::last_write_time(path, time, ec) corrigido no iOS, TvOS e WatchOSfs::directory_entry::refresh() agora, consistentemente com status() não colocará symblinks para alvos inexistentes, mas faça a entrada ter file_type::not_found como o tipoEINTR na iteração do diretório POSIX e a cópia do arquivo para evitar erros nos sistemas de arquivos de redefs::copy_file() agora também copia as permissõesfs::copy_file() ignorando a opção skip_existing .GHC_NO_DIRENT_D_TYPE em sistemas que não suportam dirent::d_type e configuração e testes de construção corrigidos para suportar o Solaris como nova plataforma.PATH_MAX , um será definido.fs::remove_all Agora, basta excluir links simbólicos em vez de segui -los.fs::space , onde um estouro numérico pode acontecer em uma multiplicação.fs::create_directories no Windows não quebra mais em nomes de arquivos longos.ghc::filesystem tratado Pasta/volumes montados erroneamente como links simbólicos, liderando fs::canonical em falhar nos caminhos que os contêm.recursive_directory_iterator não tentará inserir symlinks mortos.fs::remove falhou quando o caminho apontou para uma entrada somente leitura, consulte também (Microsoft/STL #1511) para obter o problema correspondente no std::fs no Windows.GHC_NO_DIRENT_D_TYPE permite que a detecção do sistema operacional suportasse sistemas sem o membro dirent.d_type , suporte experimental do primeiro QNX como caso de uso inicial, corrigido o problema com os sistemas de arquivos que retornam dt_unknown (por exemplo, reiserfs).string_view quando o CLANG com LIBSTDC ++ é detectado.<Availability.h> foi incluída antes de <ghc/fs_std.hpp> ou <ghc/fs_std_fwd.hpp> / <ghc/fs_std_impl.hpp> .std::filesystem são suportados e foi substituído pelos nomes de capítulos semelhantes a tags que permanecem (principalmente) consistentes sobre as versões.recursive_directory_iterator em árvores grandes agora em algum lugar entre libc ++ e libstdc ++.ghc::filesystem agora tem suporte preliminar para o Cygwin. Alterações onde foram feitas para permitir que os testes compilem e executem com sucesso (testados com o GCC 10.2.0), feedback e PRs adicionais são bem -vindos, pois atualmente não faz parte da configuração do CI.GHC_FILESYSTEM_BUILD_STD_TESTING para substituir a construção adicional das std::filesystem dos testes para comparação e a possibilidade de usar GHC_FILESYSTEM_TEST_COMPILE_FEATURES para preencher os recursos usados que estão de acordo com CMAKE_CXX_COMPILE_FEATURES .directory_entry leva a cerca de 20% a 25% em testes com recursive_directory_iterator em uma árvore de diretório maior.wchar_t não estava na lista de tipos de char suportados nos back-ends não-Windows.string_view aprimorado usa o <string_view> ou <experimental/string_view> quando disponível, e permite o uso da implementação do Custom basic_string_view ao definir GHC_HAS_CUSTOM_STRING_VIEW e importar a visualização da String para o ghc::filesystem Namespace Antes de incluir o System Header.std::filesystem Testes agora vinculam -se a -lrt para evitar problemas.fs::hard_link_count falhou devido ao comportamento dos sistemas de arquivos, o caso de teste foi adaptado para levar isso em consideração.GHC_FS_API e GHC_FS_API_CLASS agora são homenageados quando definidos de fora para permitir a substituição do comportamento.make install .GHC_FILESYSTEM_BUILD_TESTING , GHC_FILESYSTEM_BUILD_EXAMPLES e GHC_FILESYSTEM_WITH_INSTALL onde implementado, proibido para configurá -los de um projeto pai ao usar esse add_subdirectory , que a correção os permite para defini -los novamente.fs::path foi originalmente criada a partir da implementação baseada em POSIX, foi, pela adaptação das strings de entrada e saída. Isso resultou em um cache mutável dentro fs::path no Windows, que não era inerentemente seguro, mesmo para métodos const . Para não adicionar patches adicionais a uma solução abaixo do ideal, desta vez eu reformulei o código path para armazenar agora a representação do caminho nativo . Isso mudou muito código, mas quando combinado com wchar_t como value_type ajudou a evitar muita conversão para chamadas para Win-API.fs::path::native() e fs::path::c_str() agora podem ser noexcept como os mandatos padrãowchar_t agora é o padrão para fs::path::value_type e std::wstring é o padrão para fs::path::string_type .const de fs::path não é mais um problemaGHC_WIN_DISABLE_AUTO_PREFIXES , para todos os outros tipos de prefixos ou namespaces, o comportamento segue o do MSVC std::filesystem::pathchar / std::string ainda seja necessária, ela pode ser ativada com GHC_WIN_DISABLE_WSTRING_STORAGE_TYPEfs::file_status agora suporta operator== Introduzido no std::filesystem com C ++ 20.fs::path::parent_path() teve um problema de desempenho, pois ainda estava usando uma abordagem baseada em loop para recriar o pai da Elements. Isso criou muitos temporários e foi muito lento, especialmente em caminhos longos.char8_t e std::u8string são suportados onde Source é o tipo de parâmetrofs::path::u8string() e fs::path::generic_u8string() agora retorna um std::u8string<=> agora é suportado para fs::pathGHC_FILESYSTEM_ENFORCE_CPP17_API ghc::filesystem voltará ao antigo fs::path::u8string() e fs::path::generic_u8string() API se preferirfs::proximate(p, ec) onde a chamada interna para fs::current_path() não estava usando a variante error_code , lançando possíveis exceções em vez de definir ec .LWG_2936_BEHAVIOUR está agora por padrão.Source que são visualizações de string.constexpr .__MAC_OS_X_VERSION_MIN_REQUIRED para garantir que std::filesystem seja selecionado apenas no MacOS se o destino de implantação for pelo menos Catalina.directory_iterator e o recursive_directory_iterator tiveram um problema com a opção skip_permission_denied , que leva à incapacidade de pular pastas protegidas SIP no macOS._MSVC_LANG agora é usado quando disponível, além de __cplusplus , nos cabeçalhos de ajuda para permitir que eles funcionem mesmo quando /Zc:__cplusplus não é usado.false no fs::exists ou não-erros não encontrados no fs::status . Os caminhos nomes do espaço não são mais filtrados.TestAllocator no filesystem_test.cpp foi concluído para atender aos requisitos para construir no CentOS 7 com devtoolset-9 . O CentOS 7 e o CentOS 8 agora fazem parte das construções do IC.LWG_2936_BEHAVIOUR que permite ativar o post C ++ 17 fs::path::compare Comportado, onde a comparação é como se fosse uma comparação de caminho de elemento, conforme descrito no LWG 2936 e C ++ 20 [fs.path.compare] . É padrão em v1.3.6 e será padrão a partir da v1.4.0, à medida que altera a ordem.wchar_t de std::fstream do ghc::filesystem::fstream Wrappers no Windows se estiver usando o GCC com libc ++.fs::directory_options::skip_permission_denied e suporte inicial para compilação com EMSCRIPTEN.ghc::filesystem agora suporta o uso em projetos com exceções desativadas. As assinaturas da API usando exceções para o tratamento de erros não estão disponíveis neste modo, obrigado pelo PR (isso resolve #60 e #43)ERROR_FILE_TOO_LARGE indefinido_file_too_large.fs::lexically_relative não ignorou a barra no parâmetro base, obrigado pelo 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.