Como você itera por meio de cada arquivo / diretório recursivamente no C ++ padrão?
c++
filesystems
Robottobor
fonte
fonte
Respostas:
No C ++ padrão, tecnicamente não há como fazer isso, pois o C ++ padrão não tem concepção de diretórios. Se você quiser expandir sua rede um pouco, você pode querer dar uma olhada em Boost.FileSystem . Isso foi aceito para inclusão no TR2, portanto, oferece a melhor chance de manter sua implementação o mais próximo possível do padrão.
Um exemplo, retirado diretamente do site:
fonte
Do C ++ 17 em diante, o
<filesystem>
cabeçalho e o intervalofor
, você pode simplesmente fazer isso:A partir do C ++ 17,
std::filesystem
faz parte da biblioteca padrão e pode ser encontrado no<filesystem>
cabeçalho (não é mais "experimental").fonte
using
, use em seunamespace
lugar.Se estiver usando a API Win32, você pode usar as funções FindFirstFile e FindNextFile .
http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx
Para travessia recursiva de diretórios, você deve inspecionar cada WIN32_FIND_DATA.dwFileAttributes para verificar se o bit FILE_ATTRIBUTE_DIRECTORY está definido. Se o bit estiver definido, você pode chamar recursivamente a função com esse diretório. Alternativamente, você pode usar uma pilha para fornecer o mesmo efeito de uma chamada recursiva, mas evitando o estouro de pilha para árvores de caminho muito longas.
fonte
Você pode torná-lo ainda mais simples com o novo intervalo C ++ 11 baseado
for
e Boost :fonte
Uma solução rápida é usar a biblioteca Dirent.h do C.
Fragmento de código de trabalho da Wikipedia:
fonte
Além do boost :: filesystem mencionado acima, você pode examinar wxWidgets :: wxDir e Qt :: QDir .
Ambos wxWidgets e Qt são frameworks C ++ de plataforma cruzada de código aberto.
wxDir
fornece uma maneira flexível de percorrer arquivos recursivamente usandoTraverse()
umaGetAllFiles()
função mais simples . Você também pode implementar a travessia com as funçõesGetFirst()
eGetNext()
(presumo que Traverse () e GetAllFiles () sejam invólucros que eventualmente usam as funções GetFirst () e GetNext ()).QDir
fornece acesso a estruturas de diretório e seu conteúdo. Existem várias maneiras de percorrer os diretórios com QDir. Você pode iterar sobre o conteúdo do diretório (incluindo subdiretórios) com QDirIterator que foi instanciado com o sinalizador QDirIterator :: Subdirectories. Outra maneira é usar a função GetEntryList () do QDir e implementar uma travessia recursiva.Aqui está um código de amostra (retirado daqui # Exemplo 8-5) que mostra como iterar em todos os subdiretórios.
fonte
Boost :: filesystem fornece recursive_directory_iterator, que é bastante conveniente para esta tarefa:
fonte
Você pode usar
ftw(3)
ounftw(3)
percorrer uma hierarquia de sistema de arquivos em C ou C ++ em sistemas POSIX .fonte
nftw()
uso.Você não. O padrão C ++ não tem conceito de diretórios. Depende da implementação transformar uma string em um identificador de arquivo. O conteúdo dessa string e o que ela mapeia dependem do sistema operacional. Lembre-se de que o C ++ pode ser usado para escrever esse sistema operacional, portanto, ele é usado em um nível em que a pergunta como iterar por meio de um diretório ainda não foi definida (porque você está escrevendo o código de gerenciamento de diretório).
Veja a documentação da API do seu sistema operacional para saber como fazer isso. Se você precisa ser portátil, terá que ter vários #ifdef s para vários sistemas operacionais.
fonte
Você provavelmente ficaria melhor com o boost ou com o sistema de arquivos experimental do c ++ 14. SE você estiver analisando um diretório interno (ou seja, usado pelo seu programa para armazenar dados depois que o programa foi fechado), faça um arquivo de índice que tenha um índice do conteúdo do arquivo. A propósito, você provavelmente precisará usar o boost no futuro, então, se não o tiver instalado, instale-o! Em segundo lugar, você pode usar uma compilação condicional, por exemplo:
O código para cada caso é retirado de https://stackoverflow.com/a/67336/7077165
fonte
Você precisa chamar funções específicas do sistema operacional para travessia do sistema de arquivos, como
open()
ereaddir()
. O padrão C não especifica nenhuma função relacionada ao sistema de arquivos.fonte
Estamos em 2019. Temos a biblioteca padrão do sistema de arquivos em
C++
. OFilesystem library
fornece recursos para executar operações em sistemas de arquivos e seus componentes, como caminhos, arquivos regulares e diretórios.Há uma observação importante neste link se você estiver considerando questões de portabilidade. Diz:
A biblioteca do sistema de arquivos foi originalmente desenvolvida como
boost.filesystem
, foi publicada como a especificação técnica ISO / IEC TS 18822: 2015 e, finalmente, foi incorporada ao ISO C ++ a partir do C ++ 17. A implementação boost está disponível atualmente em mais compiladores e plataformas do que a biblioteca C ++ 17.@ adi-shavit respondeu a esta pergunta quando fazia parte de std :: experimental e ele atualizou esta resposta em 2017. Eu quero dar mais detalhes sobre a biblioteca e mostrar um exemplo mais detalhado.
std :: filesystem :: recursive_directory_iterator é um
LegacyInputIterator
que itera sobre os elementos directory_entry de um diretório e, recursivamente, sobre as entradas de todos os subdiretórios. A ordem de iteração não é especificada, exceto que cada entrada do diretório é visitada apenas uma vez.Se você não quiser iterar recursivamente sobre as entradas de subdiretórios, então o directory_iterator deve ser usado.
Ambos os iteradores retornam um objeto de directory_entry .
directory_entry
tem várias funções de membro útil, comois_regular_file
,is_directory
,is_socket
,is_symlink
etc. Ospath()
função de membro retorna um objeto do std :: filesystem :: caminho e ele pode ser usado para obterfile extension
,filename
,root name
.Considere o exemplo abaixo. Tenho usado
Ubuntu
e compilado no terminal usandog ++ example.cpp --std = c ++ 17 -lstdc ++ fs -Wall
fonte
Você não. C ++ padrão não se expõe ao conceito de diretório. Especificamente, não fornece nenhuma maneira de listar todos os arquivos em um diretório.
Um hack horrível seria usar chamadas system () e analisar os resultados. A solução mais razoável seria usar algum tipo de biblioteca de plataforma cruzada, como Qt ou mesmo POSIX .
fonte
Você pode usar
std::filesystem::recursive_directory_iterator
. Mas cuidado, isso inclui links simbólicos (soft). Se você quiser evitá-los, você pode usaris_symlink
. Exemplo de uso:fonte
Se você estiver no Windows, pode usar FindFirstFile junto com a API FindNextFile. Você pode usar FindFileData.dwFileAttributes para verificar se um determinado caminho é um arquivo ou diretório. Se for um diretório, você pode repetir o algoritmo recursivamente.
Aqui, reuni um código que lista todos os arquivos em uma máquina Windows.
http://dreams-soft.com/projects/traverse-directory
fonte
A caminhada na árvore de arquivos
ftw
é uma forma recursiva de bloquear toda a árvore de diretórios no caminho. Mais detalhes estão aqui .NOTA: Você também pode usar o
fts
que pode pular arquivos ocultos como.
ou..
ou.bashrc
a saída tem a seguinte aparência:
Digamos que se você deseja corresponder a um nome de arquivo (exemplo: pesquisar todos os
*.jpg, *.jpeg, *.png
arquivos.) Para uma necessidade específica, usefnmatch
.fonte