Bagaimana Anda melakukan iterasi melalui setiap file / direktori secara rekursif dalam C ++ standar?
c++
filesystems
robottobor
sumber
sumber
Jawaban:
Dalam C ++ standar, secara teknis tidak ada cara untuk melakukan ini karena C ++ standar tidak memiliki konsep direktori. Jika Anda ingin memperluas jaringan Anda sedikit, Anda mungkin ingin menggunakan Boost.FileSystem . Ini telah diterima untuk disertakan dalam TR2, jadi ini memberi Anda peluang terbaik untuk menjaga penerapan Anda sedekat mungkin dengan standar.
Contoh, diambil langsung dari situs web:
sumber
Dari C ++ 17 dan seterusnya,
<filesystem>
header, dan range-for
, Anda cukup melakukan ini:Mulai C ++ 17,
std::filesystem
merupakan bagian dari pustaka standar dan dapat ditemukan di<filesystem>
header (tidak lagi "eksperimental").sumber
using
, gunakannamespace
sebagai gantinya.Jika menggunakan Win32 API Anda dapat menggunakan fungsi FindFirstFile dan FindNextFile .
http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx
Untuk traversal rekursif direktori Anda harus memeriksa setiap WIN32_FIND_DATA.dwFileAttributes untuk memeriksa apakah bit FILE_ATTRIBUTE_DIRECTORY disetel. Jika bit disetel maka Anda dapat memanggil fungsi secara rekursif dengan direktori itu. Alternatifnya, Anda dapat menggunakan tumpukan untuk memberikan efek yang sama dari panggilan rekursif tetapi menghindari tumpukan berlebih untuk pohon jalur yang sangat panjang.
sumber
Anda dapat membuatnya lebih sederhana dengan berbasis C ++ 11
for
dan Boost baru :sumber
Solusi cepat adalah menggunakan perpustakaan Dirent.h C.
Bagian kode yang berfungsi dari Wikipedia:
sumber
Selain boost :: filesystem yang disebutkan di atas, Anda mungkin ingin memeriksa wxWidgets :: wxDir dan Qt :: QDir .
Baik wxWidgets dan Qt adalah framework C ++ sumber terbuka dan lintas platform.
wxDir
menyediakan cara yang fleksibel untuk melintasi file secara rekursif menggunakanTraverse()
atauGetAllFiles()
fungsi yang lebih sederhana . Anda juga dapat mengimplementasikan traversal denganGetFirst()
danGetNext()
fungsi (saya berasumsi bahwa Traverse () dan GetAllFiles () adalah pembungkus yang akhirnya menggunakan fungsi GetFirst () dan GetNext ()).QDir
menyediakan akses ke struktur direktori dan isinya. Ada beberapa cara untuk menjelajahi direktori dengan QDir. Anda dapat mengulang isi direktori (termasuk sub-direktori) dengan QDirIterator yang dibuat dengan flag QDirIterator :: Subdirectories. Cara lain adalah dengan menggunakan fungsi GetEntryList () QDir dan mengimplementasikan traversal rekursif.Berikut adalah contoh kode (diambil dari sini # Contoh 8-5) yang menunjukkan bagaimana melakukan iterasi pada semua sub direktori.
sumber
Boost :: filesystem menyediakan recursive_directory_iterator, yang cukup nyaman untuk tugas ini:
sumber
Anda dapat menggunakan
ftw(3)
ataunftw(3)
menjalankan hierarki sistem file di C atau C ++ pada sistem POSIX .sumber
nftw()
penggunaan.Kamu tidak. Standar C ++ tidak memiliki konsep direktori. Terserah pada implementasi untuk mengubah string menjadi pegangan file. Isi dari string itu dan apa yang dipetakannya bergantung pada OS. Perlu diingat bahwa C ++ dapat digunakan untuk menulis OS tersebut, sehingga digunakan pada level di mana menanyakan cara melakukan iterasi melalui direktori belum ditentukan (karena Anda sedang menulis kode manajemen direktori).
Lihat dokumentasi OS API Anda untuk mengetahui cara melakukannya. Jika Anda perlu portabel, Anda harus memiliki banyak #ifdef untuk berbagai OS.
sumber
Anda mungkin akan lebih baik jika menggunakan boost atau eksperimental c ++ 14 filesystem. JIKA Anda mengurai direktori internal (mis. Digunakan untuk program Anda untuk menyimpan data setelah program ditutup), maka buatlah file indeks yang memiliki indeks dari isi file. Ngomong-ngomong, Anda mungkin perlu menggunakan boost di masa mendatang, jadi jika Anda belum menginstalnya, instal! Kedua, Anda dapat menggunakan kompilasi bersyarat, misalnya:
Kode untuk setiap kasus diambil dari https://stackoverflow.com/a/67336/7077165
sumber
Anda perlu memanggil fungsi khusus OS untuk traversal sistem file, seperti
open()
danreaddir()
. Standar C tidak menentukan fungsi apa pun yang terkait dengan sistem file.sumber
Kami berada di tahun 2019. Kami memiliki perpustakaan standar sistem file di
C++
. ItuFilesystem library
menyediakan fasilitas untuk melakukan operasi pada sistem file dan komponen mereka, seperti jalur, file biasa, dan direktori.Ada catatan penting di tautan ini jika Anda mempertimbangkan masalah portabilitas. Ia mengatakan:
Perpustakaan sistem file awalnya dikembangkan sebagai
boost.filesystem
, diterbitkan sebagai spesifikasi teknis ISO / IEC TS 18822: 2015, dan akhirnya digabungkan ke ISO C ++ pada C ++ 17. Implementasi boost saat ini tersedia di lebih banyak kompiler dan platform daripada library C ++ 17.@ adi-shavit telah menjawab pertanyaan ini ketika itu adalah bagian dari std :: eksperimental dan dia telah memperbarui jawaban ini pada tahun 2017. Saya ingin memberikan detail lebih lanjut tentang perpustakaan dan menampilkan contoh yang lebih detail.
std :: filesystem :: recursive_directory_iterator adalah
LegacyInputIterator
yang mengulangi elemen directory_entry dari sebuah direktori, dan, secara rekursif, atas entri dari semua subdirektori. Urutan iterasi tidak ditentukan, kecuali bahwa setiap entri direktori hanya dikunjungi sekali.Jika Anda tidak ingin mengulang entri subdirektori secara rekursif, maka directory_iterator harus digunakan.
Kedua iterator mengembalikan objek directory_entry .
directory_entry
memiliki berbagai fungsi anggota yang berguna sepertiis_regular_file
,is_directory
,is_socket
,is_symlink
dllpath()
fungsi anggota kembali sebuah objek dari std :: filesystem :: jalan dan dapat digunakan untuk mendapatkanfile extension
,filename
,root name
.Perhatikan contoh di bawah ini. Saya telah menggunakan
Ubuntu
dan menyusunnya melalui terminal menggunakang ++ example.cpp --std = c ++ 17 -lstdc ++ fs -Wall
sumber
Kamu tidak. Standar C ++ tidak mengekspos konsep direktori. Secara khusus itu tidak memberikan cara apa pun untuk mencantumkan semua file dalam sebuah direktori.
Peretasan yang mengerikan adalah menggunakan pemanggilan system () dan mengurai hasilnya. Solusi yang paling masuk akal adalah dengan menggunakan semacam pustaka lintas platform seperti Qt atau bahkan POSIX .
sumber
Anda bisa menggunakan
std::filesystem::recursive_directory_iterator
. Namun berhati-hatilah karena ini termasuk tautan simbolis (lunak). Jika Anda ingin menghindarinya, Anda dapat menggunakanis_symlink
. Contoh penggunaan:sumber
Jika Anda menggunakan Windows, Anda dapat menggunakan FindFirstFile bersama dengan FindNextFile API. Anda dapat menggunakan FindFileData.dwFileAttributes untuk memeriksa apakah jalur yang diberikan adalah file atau direktori. Jika ini adalah direktori, Anda dapat mengulangi algoritme secara rekursif.
Di sini, saya telah mengumpulkan beberapa kode yang mencantumkan semua file di mesin Windows.
http://dreams-soft.com/projects/traverse-directory
sumber
File tree walk
ftw
adalah cara rekursif untuk memagari seluruh pohon direktori di jalur. Detail selengkapnya ada di sini .CATATAN: Anda juga dapat menggunakan
fts
yang dapat melewati file tersembunyi seperti.
atau..
atau.bashrc
keluarannya terlihat seperti berikut:
Katakanlah jika Anda ingin mencocokkan nama file (contoh: mencari semua
*.jpg, *.jpeg, *.png
file.) Untuk kebutuhan tertentu, gunakanfnmatch
.sumber