Apa yang akan menyenangkan jika DirectoryInfo memiliki metode seperti .Clean ();
JL.
6
atau .DeleteFolders, dan metode DeleteFiles.
JL.
18
Anda ingin mengetahui bahwa Menghapus Anda dapat dengan mudah melempar pengecualian jika file terkunci (atau jika Anda tidak memiliki hak). Lihat FileInfo.Delete untuk daftar pengecualian.
Shane Courtrille
Jawaban:
834
System.IO.DirectoryInfo di =newDirectoryInfo("YourPath");foreach(FileInfo file in di.GetFiles()){
file.Delete();}foreach(DirectoryInfo dir in di.GetDirectories()){
dir.Delete(true);}
Jika direktori Anda mungkin memiliki banyak file, EnumerateFiles()lebih efisien daripada GetFiles(), karena ketika Anda menggunakan EnumerateFiles()Anda dapat mulai menghitungnya sebelum seluruh koleksi dikembalikan, sebagai lawan di GetFiles()mana Anda perlu memuat seluruh koleksi dalam memori sebelum mulai menghitungnya. Lihat kutipan ini di sini :
Karenanya, saat Anda bekerja dengan banyak file dan direktori, EnumerateFiles () dapat lebih efisien.
Hal yang sama berlaku untuk EnumerateDirectories()dan GetDirectories(). Jadi kodenya adalah:
foreach(FileInfo file in di.EnumerateFiles()){
file.Delete();}foreach(DirectoryInfo dir in di.EnumerateDirectories()){
dir.Delete(true);}
Untuk keperluan pertanyaan ini, sebenarnya tidak ada alasan untuk menggunakan GetFiles()dan GetDirectories().
Apa itu tentang stackoverflow.com/questions/12415105/... "Ketika Anda memanggil Directory.Delete dan sebuah file terbuka sedemikian rupa, Directory.Delete berhasil menghapus semua file tetapi ketika Directory.Delete memanggil RemoveDirectory sebuah" direktori tidak kosong " pengecualian dilemparkan karena ada file yang ditandai untuk dihapus tetapi sebenarnya tidak dihapus. "
Kiquenet
74
DirectoryInfo lambat karena ini mengumpulkan lebih banyak data lainnya. BTW: Directory.Delete(path, true)akan mengurus semuanya :)
AcidJunkie
57
@AcidJunkie, Itu juga akan menghapus direktori yang dimaksud, sedangkan OP secara khusus meminta direktori root untuk disimpan.
Marc L.
5
Perhatikan bahwa ini tidak akan berfungsi jika ada file yang hanya baca. Anda harus menghapus tanda baca-saja sebelum menelepon file.Delete().
Ben
8
Ini tampaknya tidak berfungsi jika sub-direktori berisi file.
cdiggins
174
Ya, itulah cara yang benar untuk melakukannya. Jika Anda ingin memberi diri Anda fungsi "Bersihkan" (atau, seperti saya lebih suka menyebutnya, fungsi "Kosong"), Anda dapat membuat metode ekstensi.
publicstaticvoidEmpty(thisSystem.IO.DirectoryInfo directory){foreach(System.IO.FileInfo file in directory.GetFiles()) file.Delete();foreach(System.IO.DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true);}
Ini kemudian akan memungkinkan Anda untuk melakukan sesuatu seperti ..
Baris terakhir adalah subDirectory.Delete (true), bukan direktori.Delete (true). Saya hanya memotong dan menempelkan kode dan menghapus direktori utama itu sendiri. Terima kasih untuk kodenya bagus!
Aximili
26
catatan yang sudah Emptyada di C #, untuk string. Jika saya melihat sesuatu yang bernama Emptysaya akan terkejut jika itu memodifikasi objek (atau filesystem) daripada memberi saya boolyang mengatakan apakah itu kosong atau tidak. Karena itu, saya akan menggunakan nama itu Clean.
Default
5
@ Kesalahan: Saya tidak berpikir fakta bahwa satu jenis memiliki properti sudah harus memiliki kaitan pada apakah jenis lain (sama sekali tidak terkait) harus memilikinya; dan konvensi untuk properti dan fungsi yang mengindikasikan status untuk kata-kata yang juga bisa menjadi kata kerja adalah untuk mengawali kata-kata tersebut Is(yaitu, IsEmptybukan Empty).
Adam Robinson
3
@AdamRobinson Hanya ingin mencatatnya. Bagi saya , apa yang dimiliki Microsoft dalam kode mereka memiliki kaitan. Tapi itu untuk semua orang menafsirkan :)
Default
4
@simonhaines: Inti pertanyaannya adalah mengosongkan direktori (mis. hapus semua yang ada di dalamnya ), bukan untuk menghapus direktori itu sendiri.
Adam Robinson
77
Kode berikut akan menghapus folder secara rekursif:
privatevoid clearFolder(stringFolderName){DirectoryInfo dir =newDirectoryInfo(FolderName);foreach(FileInfo fi in dir.GetFiles()){
fi.Delete();}foreach(DirectoryInfo di in dir.GetDirectories()){
clearFolder(di.FullName);
di.Delete();}}
Opsi kedua, Directory.Delete (String, Boolean) bekerja untuk saya.
Stephen MacDougall
15
Ini menghapus direktori root, di mana OP secara khusus meminta itu dipertahankan.
Marc L.
2
Deleteakan melempar jika direktori tidak ada, jadi akan lebih aman untuk melakukan Directory.Existspemeriksaan terlebih dahulu.
James
1
@ James Directory.Existstidak cukup; setelah pemeriksaan, utas lainnya mungkin telah mengganti nama atau menghapus direktori. Itu lebih aman try-catch.
andre_ss6
2
@Marv Hati-hati dengan hanya menambahkan Directory.Createkarena rekursif Directory.Deletesayangnya tidak dijamin sinkron ..
using System.IO;
using System.Linq;…var directory =Directory.GetParent(TestContext.TestDir);
directory.EnumerateFiles().ToList().ForEach(f => f.Delete());
directory.EnumerateDirectories().ToList().ForEach(d => d.Delete(true));
Perhatikan bahwa solusi saya di sini bukan Get*().ToList().ForEach(...)pemain , karena saya menggunakan yang menghasilkan IEnumerabledua kali sama . Saya menggunakan metode ekstensi untuk menghindari masalah ini:
using System.IO;
using System.Linq;…var directory =Directory.GetParent(TestContext.TestDir);
directory.EnumerateFiles().ForEachInEnumerable(f => f.Delete());
directory.EnumerateDirectories().ForEachInEnumerable(d => d.Delete(true));
Ini adalah metode ekstensi:
/// <summary>/// Extensions for <see cref="System.Collections.Generic.IEnumerable"/>./// </summary>publicstaticclassIEnumerableOfTExtensions{/// <summary>/// Performs the <see cref="System.Action"/>/// on each item in the enumerable object./// </summary>/// <typeparam name="TEnumerable">The type of the enumerable.</typeparam>/// <param name="enumerable">The enumerable.</param>/// <param name="action">The action.</param>/// <remarks>/// “I am philosophically opposed to providing such a method, for two reasons./// …The first reason is that doing so violates the functional programming principles/// that all the other sequence operators are based upon. Clearly the sole purpose of a call/// to this method is to cause side effects.”/// —Eric Lippert, “foreach” vs “ForEach” [http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx]/// </remarks>publicstaticvoidForEachInEnumerable<TEnumerable>(thisIEnumerable<TEnumerable> enumerable,Action<TEnumerable> action){foreach(var item in enumerable){
action(item);}}}
Dan jika Anda mencoba untuk menghapus subdirektori juga, foreach (var dir in info.GetDirectories("*", SearchOption.AllDirectories).OrderByDescending(dir => dir.FullName.Length)) dir.Delete();mungkin berguna.
Warty
1
Jika Anda menyukai kinerja, pertimbangkan untuk menggunakan directory.EnumerateFiles()dan directory.EnumerateDirectories()alih-alih directory.Get*()metode.
Tinister
1
Lucu, IEnumerable<T>.ForEach()ekstensi saya sendiri memiliki ringkasan komentar XML, "Pelanggaran! Pelanggaran! Tidak bersih!".
Marc L.
Hei apa alasan ke-2? Ke 3? Dll?
Bill Roberts
lol @RASX - dia berbicara kepada Anda: "Jika Anda tidak setuju dengan keberatan filosofis ini dan menemukan nilai praktis dalam pola ini, dengan segala cara, silakan dan tulis sendiri satu-liner sepele ini sendiri."
Ketahuilah bahwa ini akan menghapus izin khusus yang dimiliki jalur tersebut
Matthew Lock
6
Anda perlu menambahkan batas waktu antara kedua tindakan tersebut. coba jalankan kode ini dan Anda akan mendapatkan Pengecualian: while (true) {Directory.Delete (@ "C: \ Myfolder", true); Directory.CreateDirectory (@ "C: \ Myfolder"); }
RcMan
31
privatevoidClearFolder(stringFolderName){DirectoryInfo dir =newDirectoryInfo(FolderName);foreach(FileInfo fi in dir.GetFiles()){try{
fi.Delete();}catch(Exception){}// Ignore all exceptions}foreach(DirectoryInfo di in dir.GetDirectories()){ClearFolder(di.FullName);try{
di.Delete();}catch(Exception){}// Ignore all exceptions}}
Jika Anda tahu tidak ada sub-folder, sesuatu seperti ini mungkin yang paling mudah:
Saya menggunakan fungsi ini untuk menghapus folder temp sistem. Saya baru saja menambahkan coba-tangkap di sekitar Hapus () dan IsReadOnly untuk mengabaikan semua pengecualian, dan itu berhasil.
humbads
@Humbads, dapatkah Anda memperbarui jawaban ini, atau memasukkan kode di sini, dan saya akan memperbarui dengan perubahan Anda?
sama seperti di atas: perlu diketahui bahwa ini akan menghapus izin khusus yang dimiliki jalur.
hB0
8
Setiap metode yang saya coba, mereka gagal di beberapa titik dengan kesalahan System.IO. Metode berikut ini berfungsi dengan pasti, meskipun folder kosong atau tidak, hanya baca atau tidak, dll.
Saya selalu lebih suka rd / s / q + mkdir dalam hal pengosongan direktori.
Dawid Ohia
7
Ini bukan solusi lintas platform. Sistem mirip Unix jelas tidak memiliki cmd.exe, mereka bahkan tidak menjalankan file .exe. C # bukan hanya Windows, ada juga Mono, yang merupakan cross-platform.
Nama Tampilan
1
@SargeBorsch tidak ada persyaratan lintas platform dalam pertanyaan dan menjadi C # kemungkinan besar solusinya akan digunakan untuk Windows. Tampaknya menjadi satu-satunya jawaban yang tidak menggunakan fungsi .NET, jadi itu cukup berharga sebagai alternatif.
Alex Pandrea
7
Ini adalah alat yang saya akhiri setelah membaca semua posting. Itu benar
Hapus semua yang bisa dihapus
Mengembalikan nilai false jika beberapa file tetap ada di folder
Ini berhubungan dengan
Hanya baca file
Delay penghapusan
File terkunci
Itu tidak menggunakan Directory.Delete karena proses dibatalkan dengan pengecualian.
/// <summary>/// Attempt to empty the folder. Return false if it fails (locked files...)./// </summary>/// <param name="pathName"></param>/// <returns>true on success</returns>publicstaticboolEmptyFolder(string pathName){bool errors =false;DirectoryInfo dir =newDirectoryInfo(pathName);foreach(FileInfo fi in dir.EnumerateFiles()){try{
fi.IsReadOnly=false;
fi.Delete();//Wait for the item to disapear (avoid 'dir not empty' error).while(fi.Exists){System.Threading.Thread.Sleep(10);
fi.Refresh();}}catch(IOException e){Debug.WriteLine(e.Message);
errors =true;}}foreach(DirectoryInfo di in dir.EnumerateDirectories()){try{EmptyFolder(di.FullName);
di.Delete();//Wait for the item to disapear (avoid 'dir not empty' error).while(di.Exists){System.Threading.Thread.Sleep(10);
di.Refresh();}}catch(IOException e){Debug.WriteLine(e.Message);
errors =true;}}return!errors;}
Kode berikut akan membersihkan direktori, tetapi meninggalkan direktori root di sana (rekursif).
Action<string>DelPath=null;DelPath= p =>{Directory.EnumerateFiles(p).ToList().ForEach(File.Delete);Directory.EnumerateDirectories(p).ToList().ForEach(DelPath);Directory.EnumerateDirectories(p).ToList().ForEach(Directory.Delete);};DelPath(path);
Hanya menggunakan metode statis dengan File dan Direktori, bukan FileInfo dan DirectoryInfo akan melakukan lebih cepat. (lihat jawaban yang diterima di Apa perbedaan antara File dan FileInfo di C #? ). Jawaban ditampilkan sebagai metode utilitas.
privatevoidClearFolder(stringFolderName){DirectoryInfo dir =newDirectoryInfo(FolderName);foreach(FileInfo fi in dir.GetFiles()){
fi.IsReadOnly=false;
fi.Delete();}foreach(DirectoryInfo di in dir.GetDirectories()){ClearFolder(di.FullName);
di.Delete();}}
Pengecualian dari tipe 'System.IO.IOException' terjadi di mscorlib.dll tetapi tidak ditangani dalam kode pengguna Informasi tambahan: Direktori tidak kosong.
kipusoep
3
Di Windows 7, jika Anda baru saja membuatnya secara manual dengan Windows Explorer, struktur direktori mirip dengan yang ini:
C:
\AAA
\BBB
\CCC
\DDD
Dan menjalankan kode yang disarankan dalam pertanyaan asli untuk membersihkan direktori C: \ AAA, baris di.Delete(true)selalu gagal dengan IOException "Direktori tidak kosong" ketika mencoba untuk menghapus BBB. Mungkin karena beberapa jenis keterlambatan / caching di Windows Explorer.
Kode berikut bekerja dengan andal bagi saya:
staticvoidMain(string[] args){DirectoryInfo di =newDirectoryInfo(@"c:\aaa");CleanDirectory(di);}privatestaticvoidCleanDirectory(DirectoryInfo di){if(di ==null)return;foreach(FileSystemInfo fsEntry in di.GetFileSystemInfos()){CleanDirectory(fsEntry asDirectoryInfo);
fsEntry.Delete();}WaitForDirectoryToBecomeEmpty(di);}privatestaticvoidWaitForDirectoryToBecomeEmpty(DirectoryInfo di){for(int i =0; i <5; i++){if(di.GetFileSystemInfos().Length==0)return;Console.WriteLine(di.FullName+ i);Thread.Sleep(50* i);}}
Apa itu tentang stackoverflow.com/questions/12415105/... "Ketika Anda memanggil Directory.Delete dan sebuah file terbuka sedemikian rupa, Directory.Delete berhasil menghapus semua file tetapi ketika Directory.Delete memanggil RemoveDirectory sebuah" direktori tidak kosong " pengecualian dilemparkan karena ada file yang ditandai untuk dihapus tetapi sebenarnya tidak dihapus. "
Kiquenet
@Kiquenet: Sepertinya kami menemukan masalah di Windows. Windows dapat berkonsultasi daftar file yang ditandai untuk dihapus dan jika semua file dalam direktori ditandai untuk dihapus, jangan katakan direktori itu tidak kosong. Bagaimanapun, WaitForDirectoryToBecomeEmpty () saya adalah solusi.
farfareast
2
Versi ini tidak menggunakan panggilan rekursif, dan menyelesaikan masalah hanya baca.
publicstaticvoidEmptyDirectory(string directory){// First delete all the files, making sure they are not readonlyvar stackA =newStack<DirectoryInfo>();
stackA.Push(newDirectoryInfo(directory));var stackB =newStack<DirectoryInfo>();while(stackA.Any()){var dir = stackA.Pop();foreach(var file in dir.GetFiles()){
file.IsReadOnly=false;
file.Delete();}foreach(var subDir in dir.GetDirectories()){
stackA.Push(subDir);
stackB.Push(subDir);}}// Then delete the sub directories depth firstwhile(stackB.Any()){
stackB.Pop().Delete();}}
Contoh berikut menunjukkan bagaimana Anda bisa melakukan itu. Pertama membuat beberapa direktori dan file dan kemudian menghapusnya melalui Directory.Delete(topPath, true);:
Itu bukan cara terbaik untuk menangani masalah di atas. Tapi itu alternatif ...
while(Directory.GetDirectories(dirpath).Length>0){//Delete all files in directorywhile(Directory.GetFiles(Directory.GetDirectories(dirpath)[0]).Length>0){File.Delete(Directory.GetFiles(dirpath)[0]);}Directory.Delete(Directory.GetDirectories(dirpath)[0]);}
Bisakah Anda lebih spesifik dan menjelaskan bagaimana dan mengapa ini harus berhasil?
Deep Frozen
3
Jawaban hanya dengan kode tidak cocok. Anda harus menjelaskan bagaimana dan mengapa itu harus bekerja / menyelesaikan masalah.
rdurand
0
ini akan menunjukkan bagaimana kita menghapus folder dan memeriksanya kita menggunakan kotak teks
using System.IO;
namespace delete_the_folder
{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidDeletebt_Click(object sender,EventArgs e){//the first you should write the folder placeif(Pathfolder.Text==""){MessageBox.Show("ples write the path of the folder");Pathfolder.Select();//return;}FileAttributes attr =File.GetAttributes(@Pathfolder.Text);if(attr.HasFlag(FileAttributes.Directory))MessageBox.Show("Its a directory");elseMessageBox.Show("Its a file");string path =Pathfolder.Text;FileInfo myfileinf =newFileInfo(path);
myfileinf.Delete();}}}
publicstaticvoidDeleteDirectory(string path){if(Directory.Exists(path)){//Delete all files from the Directoryforeach(string file inDirectory.GetFiles(path)){File.Delete(file);}//Delete all child Directoriesforeach(string directory inDirectory.GetDirectories(path)){DeleteDirectory(directory);}//Delete a DirectoryDirectory.Delete(path);}}
Untuk menghapus folder, ini adalah kode menggunakan kotak teks dan tombol using System.IO;:
privatevoidDeletebt_Click(object sender,EventArgs e){System.IO.DirectoryInfo myDirInfo =newDirectoryInfo(@""+delete.Text);foreach(FileInfo file in myDirInfo.GetFiles()){
file.Delete();}foreach(DirectoryInfo dir in myDirInfo.GetDirectories()){
dir.Delete(true);}}
Lihat di bawah ... "menghapus dan menciptakan kembali" tidak sama dengan menjaga, semua penyesuaian ACL akan hilang.
Marc L.
Saya sudah mencoba sesuatu yang sangat mirip dengan ini karena saya tidak peduli dan kustomisasi ACL dan mengalami masalah dengan folder yang tidak dibuat setelahDirectory.CreateDirectory
JG di SD
-3
Satu-satunya hal yang harus Anda lakukan adalah untuk mengatur optional recursive parameteruntuk True.
Jawaban:
Jika direktori Anda mungkin memiliki banyak file,
EnumerateFiles()
lebih efisien daripadaGetFiles()
, karena ketika Anda menggunakanEnumerateFiles()
Anda dapat mulai menghitungnya sebelum seluruh koleksi dikembalikan, sebagai lawan diGetFiles()
mana Anda perlu memuat seluruh koleksi dalam memori sebelum mulai menghitungnya. Lihat kutipan ini di sini :Hal yang sama berlaku untuk
EnumerateDirectories()
danGetDirectories()
. Jadi kodenya adalah:Untuk keperluan pertanyaan ini, sebenarnya tidak ada alasan untuk menggunakan
GetFiles()
danGetDirectories()
.sumber
Directory.Delete(path, true)
akan mengurus semuanya :)file.Delete()
.Ya, itulah cara yang benar untuk melakukannya. Jika Anda ingin memberi diri Anda fungsi "Bersihkan" (atau, seperti saya lebih suka menyebutnya, fungsi "Kosong"), Anda dapat membuat metode ekstensi.
Ini kemudian akan memungkinkan Anda untuk melakukan sesuatu seperti ..
sumber
Empty
ada di C #, untukstring
. Jika saya melihat sesuatu yang bernamaEmpty
saya akan terkejut jika itu memodifikasi objek (atau filesystem) daripada memberi sayabool
yang mengatakan apakah itu kosong atau tidak. Karena itu, saya akan menggunakan nama ituClean
.Is
(yaitu,IsEmpty
bukanEmpty
).Kode berikut akan menghapus folder secara rekursif:
sumber
sumber
Delete
akan melempar jika direktori tidak ada, jadi akan lebih aman untuk melakukanDirectory.Exists
pemeriksaan terlebih dahulu.Directory.Exists
tidak cukup; setelah pemeriksaan, utas lainnya mungkin telah mengganti nama atau menghapus direktori. Itu lebih amantry-catch
.Directory.Create
karena rekursifDirectory.Delete
sayangnya tidak dijamin sinkron ..Kami juga dapat menunjukkan cinta untuk LINQ :
Perhatikan bahwa solusi saya di sini bukan
Get*().ToList().ForEach(...)
pemain , karena saya menggunakan yang menghasilkanIEnumerable
dua kali sama . Saya menggunakan metode ekstensi untuk menghindari masalah ini:Ini adalah metode ekstensi:
sumber
foreach (var dir in info.GetDirectories("*", SearchOption.AllDirectories).OrderByDescending(dir => dir.FullName.Length)) dir.Delete();
mungkin berguna.directory.EnumerateFiles()
dandirectory.EnumerateDirectories()
alih-alihdirectory.Get*()
metode.IEnumerable<T>.ForEach()
ekstensi saya sendiri memiliki ringkasan komentar XML, "Pelanggaran! Pelanggaran! Tidak bersih!".Cara paling sederhana:
Ketahuilah bahwa ini dapat menghapus beberapa izin pada folder.
sumber
Jika Anda tahu tidak ada sub-folder, sesuatu seperti ini mungkin yang paling mudah:
sumber
sumber
Setiap metode yang saya coba, mereka gagal di beberapa titik dengan kesalahan System.IO. Metode berikut ini berfungsi dengan pasti, meskipun folder kosong atau tidak, hanya baca atau tidak, dll.
sumber
Ini adalah alat yang saya akhiri setelah membaca semua posting. Itu benar
Ini berhubungan dengan
Itu tidak menggunakan Directory.Delete karena proses dibatalkan dengan pengecualian.
sumber
Kode berikut akan membersihkan direktori, tetapi meninggalkan direktori root di sana (rekursif).
sumber
Saya menggunakan
untuk menghapus gambar lama dan saya tidak memerlukan objek apa pun di folder ini
sumber
Hanya menggunakan metode statis dengan File dan Direktori, bukan FileInfo dan DirectoryInfo akan melakukan lebih cepat. (lihat jawaban yang diterima di Apa perbedaan antara File dan FileInfo di C #? ). Jawaban ditampilkan sebagai metode utilitas.
sumber
sumber
sumber
Di Windows 7, jika Anda baru saja membuatnya secara manual dengan Windows Explorer, struktur direktori mirip dengan yang ini:
Dan menjalankan kode yang disarankan dalam pertanyaan asli untuk membersihkan direktori C: \ AAA, baris
di.Delete(true)
selalu gagal dengan IOException "Direktori tidak kosong" ketika mencoba untuk menghapus BBB. Mungkin karena beberapa jenis keterlambatan / caching di Windows Explorer.Kode berikut bekerja dengan andal bagi saya:
sumber
Versi ini tidak menggunakan panggilan rekursif, dan menyelesaikan masalah hanya baca.
sumber
gunakan metode GetDirectories DirectoryInfo.
sumber
Contoh berikut menunjukkan bagaimana Anda bisa melakukan itu. Pertama membuat beberapa direktori dan file dan kemudian menghapusnya melalui
Directory.Delete(topPath, true);
:Ini diambil dari https://msdn.microsoft.com/en-us/library/fxeahc5f(v=vs.110).aspx .
sumber
Itu bukan cara terbaik untuk menangani masalah di atas. Tapi itu alternatif ...
sumber
sumber
ini akan menunjukkan bagaimana kita menghapus folder dan memeriksanya kita menggunakan kotak teks
sumber
sumber
Panggilan dari utama
Tambahkan metode ini
sumber
sumber
Untuk menghapus folder, ini adalah kode menggunakan kotak teks dan tombol
using System.IO;
:sumber
sumber
Directory.CreateDirectory
Satu-satunya hal yang harus Anda lakukan adalah untuk mengatur
optional recursive parameter
untukTrue
.Directory.Delete("C:\MyDummyDirectory", True)
Terima kasih untuk .NET. :)
sumber
Anda tidak perlu lebih dari itu
sumber