Saya ingin menyalin seluruh isi direktori dari satu lokasi ke lokasi lain di C #.
Tampaknya tidak ada cara untuk melakukan ini menggunakan System.IO
kelas tanpa banyak rekursi.
Ada metode di VB yang bisa kita gunakan jika kita menambahkan referensi ke Microsoft.VisualBasic
:
new Microsoft.VisualBasic.Devices.Computer().
FileSystem.CopyDirectory( sourceFolder, outputFolder );
Sepertinya ini hack yang agak jelek. Apakah ada cara yang lebih baik?
Microsoft.VisualBasic
dan tidakSystem.IO
? Alasannya tidak ada di Mono adalah karena semua perpustakaan yang dianggap 'inti' adalahSystem.[something]
- semua yang lain tidak. Saya tidak punya masalah merujuk DLL tambahan, tetapi ada alasan bagus mengapa Microsoft belum memasukkan fitur ini diSystem.IO
.Jawaban:
Jauh lebih mudah
sumber
Replace
memiliki masalah jika Anda memiliki pola berulang di dalam jalan, misalnya"sourceDir/things/sourceDir/things"
harus menjadi"destinationDir/things/sourceDir/things"
, tetapi jika Anda menggunakan ganti menjadi"destinationDir/things/destinationDir/things"
*.*
bukannya*
? Apakah Anda tidak ingin menyalin file tanpa ekstensi juga?Hmm, saya pikir saya salah paham pertanyaannya tapi saya akan mengambil risiko. Apa yang salah dengan metode sederhana berikut ini?
EDIT Karena posting ini telah mengumpulkan jumlah downvotes yang mengesankan untuk jawaban yang begitu sederhana untuk pertanyaan yang sama-sama sederhana, izinkan saya menambahkan penjelasan. Harap baca ini sebelum downvoting .
Pertama-tama, kode ini tidak dimaksudkan sebagai pengganti untuk kode yang ada dalam pertanyaan. Ini hanya untuk tujuan ilustrasi.
Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory
melakukan beberapa tes ketepatan tambahan (misalnya apakah sumber dan target adalah direktori yang valid, apakah sumber tersebut adalah induk dari target, dll.) yang hilang dari jawaban ini. Kode itu mungkin juga lebih dioptimalkan.Konon, kodenya berfungsi dengan baik . Ini telah (hampir identik) telah digunakan dalam perangkat lunak dewasa selama bertahun-tahun. Terlepas dari fickleness inheren yang hadir dengan semua penanganan IO (mis. Apa yang terjadi jika pengguna mencabut USB drive secara manual saat kode Anda menulisnya?), Tidak ada masalah yang diketahui.
Secara khusus, saya ingin menunjukkan bahwa penggunaan rekursi di sini sama sekali bukan masalah. Baik secara teori (secara konseptual, ini adalah solusi paling elegan) maupun dalam praktik: kode ini tidak akan meluap tumpukan . Tumpukannya cukup besar untuk menangani hierarki file yang bahkan sangat bersarang. Jauh sebelum ruang stack menjadi masalah, batasan panjang jalur folder akan muncul.
Perhatikan bahwa pengguna jahat mungkin dapat mematahkan asumsi ini dengan menggunakan direktori yang masing-masing bersarang dalam satu huruf. Saya belum mencoba ini. Tetapi hanya untuk mengilustrasikan intinya: untuk membuat kode ini meluap pada komputer biasa, direktori harus disarangkan beberapa ribu kali. Ini sama sekali bukan skenario yang realistis.
sumber
Disalin dari MSDN :
sumber
Coba ini:
Argumen xcopy Anda mungkin bervariasi tetapi Anda mendapatkan ide.
sumber
Atau, jika Anda ingin menempuh jalan yang sulit, tambahkan referensi ke proyek Anda untuk Microsoft.VisualBasic dan kemudian gunakan yang berikut ini:
Namun, menggunakan salah satu fungsi rekursif adalah cara yang lebih baik karena tidak perlu memuat dll VB.
sumber
System.IO.Directory
, tetapi lebih baik daripada menulis ulang!Situs ini selalu banyak membantu saya, dan sekarang giliran saya untuk membantu orang lain dengan apa yang saya ketahui.
Saya harap kode saya di bawah ini bermanfaat bagi seseorang.
sumber
Path.Combine()
. Jangan pernah menggunakan penggabungan string untuk menyatukan jalur file.source_dir.Length + 1
, bukansource_dir.Length
.Salin folder secara rekursif tanpa rekursi untuk menghindari stack overflow.
sumber
Inilah kelas utilitas yang saya gunakan untuk tugas-tugas IO seperti ini.
sumber
Mungkin tidak menyadari kinerja, tapi saya menggunakannya untuk folder 30MB dan berfungsi dengan sempurna. Plus, saya tidak suka semua jumlah kode dan rekursi yang diperlukan untuk tugas yang mudah.
Catatan: ZipFile tersedia di .NET 4.5+ di System.IO.Compression namespace
sumber
Peningkatan kecil pada jawaban d4nt, karena Anda mungkin ingin memeriksa kesalahan dan tidak perlu mengubah jalur xcopy jika Anda bekerja pada server dan mesin pengembangan:
sumber
Ini kode saya berharap bantuan ini
sumber
SearchOption
tanda pada pencarian folder dan file yang dilakukan dalam 4 baris kode. Periksa juga.HasFlag
ekstensi sekarang di enum.Jika Anda menyukai jawaban populer Konrad, tetapi Anda ingin
source
itu sendiri menjadi folder di bawahtarget
, daripada meletakkan anak-anak itu di bawahtarget
folder, inilah kode untuk itu. Ini mengembalikan yang baru dibuatDirectoryInfo
, yang berguna:sumber
Anda selalu dapat menggunakan ini , diambil dari situs web Microsoft.
sumber
file.CopyTo(temppath, false);
mengatakan "salin file ini ke tempat ini, hanya jika itu tidak ada", yang sebagian besar waktu tidak seperti yang kita inginkan. Tapi, saya bisa mengerti mengapa itu default untuk itu. Mungkin menambahkan tanda pada metode untuk menimpa file.tboswell mengganti versi Proof (yang tahan terhadap pola berulang dalam filepath)
sumber
Path.Combine()
. Jangan pernah menggunakan penggabungan string untuk menyatukan jalur file.Solusi saya pada dasarnya adalah modifikasi dari jawaban @ Termininja, namun saya telah meningkatkannya sedikit dan tampaknya lebih dari 5 kali lebih cepat daripada jawaban yang diterima.
EDIT: Memodifikasi @Ahmed Sabry ke full parallel foreach memang menghasilkan hasil yang lebih baik, namun kode menggunakan fungsi rekursif dan tidak ideal dalam beberapa situasi.
sumber
Maaf untuk kode sebelumnya, masih ada bug :( (menjadi mangsa masalah senjata tercepat). Di sini diuji dan berfungsi. Kuncinya adalah SearchOption.AllDirectories, yang menghilangkan kebutuhan rekursi eksplisit.
sumber
Berikut adalah metode ekstensi untuk DirectoryInfo a la FileInfo.CopyTo (perhatikan
overwrite
parameternya):sumber
Gunakan kelas ini.
sumber
.ToList().ForEach(
(yang sedikit lebih banyak pekerjaan, memori dan sedikit lebih lambat daripada hanya menyebutkan direktori secara langsung) dan sebagai metode ekstensi. Jawaban yang dipilih menggunakanSearchOption.AllDirectories
dan menghindari rekursi, jadi saya akan merekomendasikan beralih ke model itu. Juga, Anda biasanya tidak memerlukan nama tipe dalam metode ekstensi - Saya akan mengubah namaCopyTo()
itu menjadisourceDir.CopyTo(destination);
Satu varian dengan hanya satu loop untuk menyalin semua folder dan file:
sumber
Regex
, Anda mungkin juga harusRegex.Escape(path)
sebagai bagian dari komposisi ekspresi Anda (terutama mengingat pemisah jalur Windows). Anda mungkin juga mendapatkan manfaat dari membuat (dan mungkin mengkompilasi)new Regex()
objek di luar loop, daripada mengandalkan metode statis.Lebih baik daripada kode apa pun (metode ekstensi ke DirectoryInfo dengan rekursi)
sumber
Salin dan ganti semua file folder
sumber
try
catch
throw
tidak ada gunanya.Kode di bawah ini adalah saran microsoft bagaimana cara menyalin direktori dan dibagikan oleh dear @iato tetapi hanya menyalin sub direktori dan file folder sumber secara rekursif dan tidak menyalin folder sumber itu sendiri (seperti klik kanan -> salin ).
tetapi ada cara rumit di bawah jawaban ini:
jika Anda ingin menyalin isi dari sumber folder dan subfolder rekursif Anda hanya dapat menggunakannya seperti ini:
tetapi jika Anda ingin menyalin direktori sumber itu sendiri (mirip dengan yang Anda klik kanan pada folder sumber dan klik salin kemudian di folder tujuan yang Anda klik tempelkan) Anda harus menggunakan seperti ini:
sumber