Jika Anda mencoba untuk menghapus direktori a
dan direktori a\b
terbuka di Explorer secara rekursif , b
akan dihapus tetapi Anda akan mendapatkan kesalahan 'direktori tidak kosong' karena a
walaupun itu kosong ketika Anda pergi dan melihat. Direktori saat ini dari aplikasi apa pun (termasuk Explorer) mempertahankan pegangan ke direktori . Saat Anda menelepon Directory.Delete(true)
, itu dihapus dari bawah ke atas:, b
lalu a
. Jika b
terbuka di Explorer, Explorer akan mendeteksi penghapusan b
, ubah direktori ke atas cd ..
dan bersihkan pegangan yang terbuka. Karena sistem file beroperasi secara tidak sinkron, Directory.Delete
operasi gagal karena konflik dengan Explorer.
Solusi tidak lengkap
Saya awalnya memposting solusi berikut, dengan ide untuk mengganggu utas saat ini untuk memungkinkan waktu Explorer untuk melepaskan pegangan direktori.
// incomplete!
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Thread.Sleep(0);
Directory.Delete(path, true);
}
Tetapi ini hanya berfungsi jika direktori terbuka adalah anak langsung dari direktori yang Anda hapus. Jika a\b\c\d
terbuka di Explorer dan Anda menggunakan ini a
, teknik ini akan gagal setelah menghapus d
dan c
.
Solusi yang agak lebih baik
Metode ini akan menangani penghapusan struktur direktori yang dalam bahkan jika salah satu direktori tingkat bawah terbuka di Explorer.
/// <summary>
/// Depth-first recursive delete, with handling for descendant
/// directories open in Windows Explorer.
/// </summary>
public static void DeleteDirectory(string path)
{
foreach (string directory in Directory.GetDirectories(path))
{
DeleteDirectory(directory);
}
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Directory.Delete(path, true);
}
catch (UnauthorizedAccessException)
{
Directory.Delete(path, true);
}
}
Terlepas dari pekerjaan ekstra berulang pada kita sendiri, kita masih harus menangani UnauthorizedAccessException
yang dapat terjadi di sepanjang jalan. Tidak jelas apakah upaya penghapusan pertama membuka jalan untuk yang kedua, yang berhasil, atau apakah itu hanya penundaan waktu yang diperkenalkan oleh melempar / menangkap pengecualian yang memungkinkan sistem file untuk mengejar ketinggalan.
Anda mungkin dapat mengurangi jumlah pengecualian yang dilemparkan dan ditangkap dalam kondisi umum dengan menambahkan a Thread.Sleep(0)
di awal try
blok. Selain itu, ada risiko bahwa di bawah beban sistem yang berat, Anda dapat terbang melalui kedua Directory.Delete
upaya dan gagal. Pertimbangkan solusi ini sebagai titik awal untuk penghapusan rekursif yang lebih kuat.
Jawaban umum
Solusi ini hanya membahas kekhasan berinteraksi dengan Windows Explorer. Jika Anda ingin operasi penghapusan yang sangat rumit, satu hal yang perlu diingat adalah bahwa apa pun (pemindai virus, apa pun) dapat memiliki pegangan terbuka terhadap apa yang Anda coba hapus, kapan saja. Jadi, Anda harus mencoba lagi nanti. Berapa lama kemudian, dan berapa kali Anda mencoba, tergantung pada seberapa penting benda itu dihapus. Seperti yang ditunjukkan MSDN ,
Kode iterasi file yang kuat harus memperhitungkan banyak kompleksitas sistem file.
Pernyataan tidak bersalah ini, yang disediakan hanya dengan tautan ke dokumentasi referensi NTFS, harus membuat rambut Anda berdiri.
( Sunting : Banyak. Jawaban ini awalnya hanya memiliki solusi pertama dan tidak lengkap.)