Dengan menggunakan C #, bagaimana saya bisa menghapus semua file dan folder dari direktori, tetapi masih menyimpan direktori root?
Dengan menggunakan C #, bagaimana saya bisa menghapus semua file dan folder dari direktori, tetapi masih menyimpan direktori root?
Jawaban:
System.IO.DirectoryInfo di = new DirectoryInfo("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().
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.
public static void Empty(this System.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 ..
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(@"C:\...");
directory.Empty();
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.
Is(yaitu, IsEmptybukan Empty).
Kode berikut akan menghapus folder secara rekursif:
private void clearFolder(string FolderName)
{
DirectoryInfo dir = new DirectoryInfo(FolderName);
foreach(FileInfo fi in dir.GetFiles())
{
fi.Delete();
}
foreach (DirectoryInfo di in dir.GetDirectories())
{
clearFolder(di.FullName);
di.Delete();
}
}
new System.IO.DirectoryInfo(@"C:\Temp").Delete(true);
//Or
System.IO.Directory.Delete(@"C:\Temp", true);
Deleteakan melempar jika direktori tidak ada, jadi akan lebih aman untuk melakukan Directory.Existspemeriksaan terlebih dahulu.
Directory.Existstidak cukup; setelah pemeriksaan, utas lainnya mungkin telah mengganti nama atau menghapus direktori. Itu lebih aman try-catch.
Directory.Createkarena rekursif Directory.Deletesayangnya tidak dijamin sinkron ..
Kami juga dapat menunjukkan cinta untuk LINQ :
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>
public static class IEnumerableOfTExtensions
{
/// <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>
public static void ForEachInEnumerable<TEnumerable>(this IEnumerable<TEnumerable> enumerable, Action<TEnumerable> action)
{
foreach (var item in enumerable)
{
action(item);
}
}
}
foreach (var dir in info.GetDirectories("*", SearchOption.AllDirectories).OrderByDescending(dir => dir.FullName.Length)) dir.Delete();mungkin berguna.
directory.EnumerateFiles()dan directory.EnumerateDirectories()alih-alih directory.Get*()metode.
IEnumerable<T>.ForEach()ekstensi saya sendiri memiliki ringkasan komentar XML, "Pelanggaran! Pelanggaran! Tidak bersih!".
Cara paling sederhana:
Directory.Delete(path,true);
Directory.CreateDirectory(path);
Ketahuilah bahwa ini dapat menghapus beberapa izin pada folder.
private void ClearFolder(string FolderName)
{
DirectoryInfo dir = new DirectoryInfo(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:
Directory.GetFiles(folderName).ForEach(File.Delete)
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.
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C rd /s /q \"C:\\MyFolder"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
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.
/// <summary>
/// Attempt to empty the folder. Return false if it fails (locked files...).
/// </summary>
/// <param name="pathName"></param>
/// <returns>true on success</returns>
public static bool EmptyFolder(string pathName)
{
bool errors = false;
DirectoryInfo dir = new DirectoryInfo(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);
Saya menggunakan
Directory.GetFiles(picturePath).ToList().ForEach(File.Delete);
untuk menghapus gambar lama dan saya tidak memerlukan objek apa pun di folder ini
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.
public static void Empty(string directory)
{
foreach(string fileToDelete in System.IO.Directory.GetFiles(directory))
{
System.IO.File.Delete(fileToDelete);
}
foreach(string subDirectoryToDeleteToDelete in System.IO.Directory.GetDirectories(directory))
{
System.IO.Directory.Delete(subDirectoryToDeleteToDelete, true);
}
}
string directoryPath = "C:\Temp";
Directory.GetFiles(directoryPath).ToList().ForEach(File.Delete);
Directory.GetDirectories(directoryPath).ToList().ForEach(Directory.Delete);
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:
static void Main(string[] args)
{
DirectoryInfo di = new DirectoryInfo(@"c:\aaa");
CleanDirectory(di);
}
private static void CleanDirectory(DirectoryInfo di)
{
if (di == null)
return;
foreach (FileSystemInfo fsEntry in di.GetFileSystemInfos())
{
CleanDirectory(fsEntry as DirectoryInfo);
fsEntry.Delete();
}
WaitForDirectoryToBecomeEmpty(di);
}
private static void WaitForDirectoryToBecomeEmpty(DirectoryInfo di)
{
for (int i = 0; i < 5; i++)
{
if (di.GetFileSystemInfos().Length == 0)
return;
Console.WriteLine(di.FullName + i);
Thread.Sleep(50 * i);
}
}
Versi ini tidak menggunakan panggilan rekursif, dan menyelesaikan masalah hanya baca.
public static void EmptyDirectory(string directory)
{
// First delete all the files, making sure they are not readonly
var stackA = new Stack<DirectoryInfo>();
stackA.Push(new DirectoryInfo(directory));
var stackB = new Stack<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 first
while (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);:
static void Main(string[] args)
{
string topPath = @"C:\NewDirectory";
string subPath = @"C:\NewDirectory\NewSubDirectory";
try
{
Directory.CreateDirectory(subPath);
using (StreamWriter writer = File.CreateText(subPath + @"\example.txt"))
{
writer.WriteLine("content added");
}
Directory.Delete(topPath, true);
bool directoryExists = Directory.Exists(topPath);
Console.WriteLine("top-level directory exists: " + directoryExists);
}
catch (Exception e)
{
Console.WriteLine("The process failed: {0}", e.Message);
}
}
Ini diambil dari https://msdn.microsoft.com/en-us/library/fxeahc5f(v=vs.110).aspx .
Itu bukan cara terbaik untuk menangani masalah di atas. Tapi itu alternatif ...
while (Directory.GetDirectories(dirpath).Length > 0)
{
//Delete all files in directory
while (Directory.GetFiles(Directory.GetDirectories(dirpath)[0]).Length > 0)
{
File.Delete(Directory.GetFiles(dirpath)[0]);
}
Directory.Delete(Directory.GetDirectories(dirpath)[0]);
}
DirectoryInfo Folder = new DirectoryInfo(Server.MapPath(path));
if (Folder .Exists)
{
foreach (FileInfo fl in Folder .GetFiles())
{
fl.Delete();
}
Folder .Delete();
}
ini akan menunjukkan bagaimana kita menghapus folder dan memeriksanya kita menggunakan kotak teks
using System.IO;
namespace delete_the_folder
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Deletebt_Click(object sender, EventArgs e)
{
//the first you should write the folder place
if (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");
else
MessageBox.Show("Its a file");
string path = Pathfolder.Text;
FileInfo myfileinf = new FileInfo(path);
myfileinf.Delete();
}
}
}
using System.IO;
string[] filePaths = Directory.GetFiles(@"c:\MyDir\");
foreach (string filePath in filePaths)
File.Delete(filePath);
Panggilan dari utama
static void Main(string[] args)
{
string Filepathe =<Your path>
DeleteDirectory(System.IO.Directory.GetParent(Filepathe).FullName);
}
Tambahkan metode ini
public static void DeleteDirectory(string path)
{
if (Directory.Exists(path))
{
//Delete all files from the Directory
foreach (string file in Directory.GetFiles(path))
{
File.Delete(file);
}
//Delete all child Directories
foreach (string directory in Directory.GetDirectories(path))
{
DeleteDirectory(directory);
}
//Delete a Directory
Directory.Delete(path);
}
}
Untuk menghapus folder, ini adalah kode menggunakan kotak teks dan tombol using System.IO;:
private void Deletebt_Click(object sender, EventArgs e)
{
System.IO.DirectoryInfo myDirInfo = new DirectoryInfo(@"" + delete.Text);
foreach (FileInfo file in myDirInfo.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in myDirInfo.GetDirectories())
{
dir.Delete(true);
}
}
private void ClearDirectory(string path)
{
if (Directory.Exists(path))//if folder exists
{
Directory.Delete(path, true);//recursive delete (all subdirs, files)
}
Directory.CreateDirectory(path);//creates empty directory
}
Directory.CreateDirectory
IO.Directory.Delete(HttpContext.Current.Server.MapPath(path), True)
Anda tidak perlu lebih dari itu