Saya ingin cara mudah untuk membuat banyak direktori di C ++ / Linux.
Misalnya saya ingin menyimpan file lola.file di direktori:
/tmp/a/b/c
tetapi jika direktori tidak ada, saya ingin mereka dibuat secara otomatis. Contoh yang berhasil akan sempurna.
Jawaban:
Dengan C ++ 17 atau yang lebih baru, ada header standar
<filesystem>
dengan fungsistd::filesystem::create_directories
yang harus digunakan dalam program C ++ modern. Fungsi standar C ++ tidak memiliki argumen izin eksplisit (mode) spesifik POSIX.Namun, inilah fungsi C yang dapat dikompilasi dengan kompiler C ++.
Makro
STRDUP()
danFREE()
merupakan versi pemeriksaan kesalahan daristrdup()
danfree()
, dideklarasikan diemalloc.h
(dan diterapkan diemalloc.c
danestrdup.c
). The"sysstat.h"
penawaran header dengan versi rusak dari<sys/stat.h>
dan dapat digantikan oleh<sys/stat.h>
pada sistem Unix modern (tapi ada banyak masalah kembali pada tahun 1990). Dan"mkpath.h"
menyatakanmkpath()
.Perubahan antara v1.12 (versi asli dari jawaban) dan v1.13 (versi jawaban yang diubah) adalah ujian untuk
EEXIST
dido_mkdir()
. Hal ini ditunjukkan seperlunya oleh Switch - terima kasih, Switch. Kode tes telah ditingkatkan dan mereproduksi masalah pada MacBook Pro (2,3GHz Intel Core i7, menjalankan Mac OS X 10.7.4), dan menyarankan bahwa masalah telah diperbaiki dalam revisi (tetapi pengujian hanya dapat menunjukkan adanya bug , tidak pernah ketidakhadiran mereka). Kode yang ditampilkan sekarang adalah v1.16; ada perubahan kosmetik atau administratif yang dibuat sejak v1.13 (seperti penggunaan sebagaimkpath.h
gantijlss.h
dan menyertakan<unistd.h>
tanpa syarat dalam kode pengujian saja). Masuk akal untuk berpendapat bahwa"sysstat.h"
harus diganti<sys/stat.h>
kecuali jika Anda memiliki sistem bandel yang tidak biasa.(Anda dengan ini diberi izin untuk menggunakan kode ini untuk tujuan apa pun dengan atribusi.)
Kode ini tersedia di repositori SOQ (Stack Overflow Questions) saya di GitHub sebagai file
mkpath.c
danmkpath.h
(dll.) Di sub-direktori src / so-0067-5039 .sumber
if (errno != EEXIST) { status = -1; }
ketika mkdir gagal.stat()
sebelumnyamkdir()
; ini adalah masalah TOCTOU (waktu pemeriksaan, waktu penggunaan). Saya mencoba menggelitik bug dengan skrip shell yang menjalankan 13 proses di latar belakang yang menciptakan jalur 29 elemen yang sama, dan tidak berhasil melakukannya. Kemudian saya meng-hack program uji coba ke garpu 20 kali dan meminta setiap anak mencobanya, dan itu berhasil mengenai bug. Kode tetap akan memilikiif (mkdir(path, mode) != 0 && errno != EEXIST) status = -1;
. Itu tidak menunjukkan bugnya.jlss.h
,emalloc.h
), bukan perpustakaan. Namun, kode ini tersedia di repositori SOQ (Stack Overflow Questions) saya di GitHub sebagai filejlss.h
,emalloc.c
danemalloc.h
di sub-direktori src / libsoq . Anda harusposixver.h
juga, dan beberapa orang lainnya (debug.h
,stderr.c
,stderr.h
- saya pikir itu saja, tapi apa yang Anda perlu semua harus dalam direktori itu).Mudah dengan Boost.Filesystem:
create_directories
Mengembalikan:
true
jika direktori baru dibuat, sebaliknyafalse
.sumber
The <filesystem> header is not part of C++11; it is a proposal for C++ TR2 based on the Boost.Filesystem library. Visual C++ 2012 includes an implementation of the proposed library.
adalah cara terpendek yang dapat saya pikirkan (dalam hal panjang kode, belum tentu waktu eksekusi).
Ini bukan lintas platform tetapi akan berfungsi di Linux.
sumber
Dari sini . Anda mungkin harus melakukan mkdir terpisah untuk / tmp, / tmp / a, / tmp / a / b / dan kemudian / tmp / a / b / c karena tidak ada yang setara dengan flag -p di C api. Pastikan dan abaikan errno EEXISTS saat Anda melakukan yang tingkat atas.
sumber
("/tmp/",...)
,("/tmp/a/",...)
,("/tmp/a/b/",...)
,("/tmp/a/b/c/",...)
Berikut adalah contoh kode saya (berfungsi untuk Windows dan Linux):
Pemakaian:
sumber
stat
(terkait dengan__STDC__
) tidak perlu uji precompiler.Perlu dicatat bahwa mulai dari antarmuka sistem file C ++ 17 adalah bagian dari pustaka standar. Ini berarti bahwa seseorang dapat memiliki berikut ini untuk membuat direktori:
Info lebih lanjut di sini: https://en.cppreference.com/w/cpp/filesystem/create_directory
Selain itu, dengan gcc, seseorang perlu "-std = c ++ 17" ke CFLAGS. Dan "-lstdc ++ fs" ke LDLIBS. Potensi yang terakhir tidak akan dibutuhkan di masa depan.
sumber
Ini mirip dengan yang sebelumnya tetapi bekerja maju melalui string alih-alih mundur secara rekursif. Meninggalkan errno dengan nilai yang tepat untuk kegagalan terakhir. Jika ada garis miring di depan, ada waktu tambahan melalui loop yang dapat dihindari melalui satu find_first_of () di luar loop atau dengan mendeteksi leading / dan pengaturan pra ke 1. Efisiensinya sama baik kita disiapkan oleh a loop pertama atau panggilan pra-loop, dan kompleksitas akan (sedikit) lebih tinggi saat menggunakan panggilan pra-loop.
sumber
Anda mengatakan "C ++" tetapi semua orang di sini tampaknya berpikir "Bash shell."
Lihat kode sumber ke gnu
mkdir
; lalu Anda dapat melihat cara mengimplementasikan perintah shell di C ++.sumber
sumber
Jadi saya perlu
mkdirp()
hari ini, dan menemukan solusi di halaman ini terlalu rumit. Oleh karena itu saya menulis potongan yang cukup pendek, yang mudah disalin bagi orang lain yang tersandung pada utas ini heran mengapa kita membutuhkan begitu banyak baris kode.mkdirp.h
mkdirp.cpp
Jika Anda tidak menyukai casting const dan memodifikasi string untuk sementara, lakukan a
strdup()
danfree()
setelahnya.sumber
Karena posting ini memiliki peringkat tinggi di Google untuk "Buat Pohon Direktori", saya akan memposting jawaban yang akan bekerja untuk Windows - ini akan bekerja menggunakan Win32 API yang dikompilasi untuk UNICODE atau MBCS. Ini porting dari kode Mark di atas.
Karena ini adalah Windows yang kami gunakan, pemisah direktori adalah garis miring BACK, bukan garis miring ke depan. Jika Anda lebih suka menggunakan garis miring ke depan, ubah
'\\'
ke'/'
Ini akan bekerja dengan:
dan
(yaitu: tidak perlu garis miring, jadi Anda tidak perlu memeriksanya.)
Sebelum mengatakan "Cukup gunakan SHCreateDirectoryEx () di Windows", perhatikan bahwa SHCreateDirectoryEx () sudah usang dan dapat dihapus kapan saja dari versi Windows yang akan datang.
sumber
c:\this\is\a/mixed/path\of\slashes
Biasanya garis miring Windows adalah garis miring terbalik. Apa yang harus terjadi adalah pemanggil harus membersihkan jalur dan memastikan semua garis miring tepat sebelum memanggil metode ini.Saya tahu itu pertanyaan lama tetapi muncul tinggi di hasil pencarian google dan jawaban yang diberikan di sini tidak benar-benar dalam C ++ atau agak terlalu rumit.
Harap dicatat bahwa dalam contoh saya createDirTree () sangat sederhana karena semua pengangkatan berat (pemeriksaan kesalahan, validasi jalur) perlu dilakukan oleh createDir (). Juga createDir () harus mengembalikan nilai true jika direktori sudah ada atau semuanya tidak berfungsi.
Inilah cara saya melakukannya di C ++:
Tentu saja fungsi createDir () akan spesifik untuk sistem dan sudah ada cukup banyak contoh di jawaban lain bagaimana menulisnya untuk linux, jadi saya memutuskan untuk melewatkannya.
sumber
Jika dir tidak ada, buatlah:
sumber
Begitu banyak pendekatan telah dijelaskan di sini, tetapi kebanyakan dari mereka membutuhkan pengkodean keras jalur Anda ke dalam kode Anda. Ada solusi mudah untuk masalah itu, menggunakan QDir dan QFileInfo, dua kelas kerangka kerja Qt. Karena Anda sudah berada di lingkungan Linux, Qt harus mudah digunakan.
Pastikan Anda memiliki akses tulis ke Path itu.
sumber
sumber
-p
pilihan adalah apa yang saya cari. Terima kasih!Berikut adalah fungsi rekursif C / C ++ yang digunakan
dirname()
untuk melintasi dari bawah ke atas pohon direktori. Ini akan berhenti begitu menemukan leluhur yang ada.sumber
Yang lain memberi Anda jawaban yang benar, tetapi saya pikir saya akan mendemonstrasikan hal lain yang dapat Anda lakukan:
Akan membuat jalur berikut:
Tanda kurung memungkinkan Anda membuat beberapa direktori sekaligus pada tingkat hierarki yang sama, sedangkan
-p
opsi berarti "buat direktori induk sesuai kebutuhan".sumber