การใช้ C # ฉันจะลบไฟล์และโฟลเดอร์ทั้งหมดจากไดเรกทอรี แต่ยังคงเก็บไดเรกทอรีรากได้อย่างไร
การใช้ C # ฉันจะลบไฟล์และโฟลเดอร์ทั้งหมดจากไดเรกทอรี แต่ยังคงเก็บไดเรกทอรีรากได้อย่างไร
คำตอบ:
System.IO.DirectoryInfo di = new DirectoryInfo("YourPath");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
หากไดเรกทอรีของคุณอาจมีไฟล์จำนวนมากEnumerateFiles()
จะมีประสิทธิภาพมากกว่าGetFiles()
เพราะเมื่อคุณใช้EnumerateFiles()
คุณสามารถเริ่มนับได้ก่อนที่จะส่งคืนคอลเลกชันทั้งหมดซึ่งตรงข้ามกับGetFiles()
ตำแหน่งที่คุณต้องโหลดคอลเลกชันทั้งหมดในหน่วยความจำก่อนเริ่มนับ ดูคำพูดนี้ที่นี่ :
ดังนั้นเมื่อคุณทำงานกับไฟล์และไดเรกทอรีจำนวนมาก EnumerateFiles () อาจมีประสิทธิภาพมากกว่า
เช่นเดียวกับและEnumerateDirectories()
GetDirectories()
ดังนั้นรหัสจะเป็น:
foreach (FileInfo file in di.EnumerateFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.EnumerateDirectories())
{
dir.Delete(true);
}
สำหรับวัตถุประสงค์ของคำถามนี้มีจริงๆเหตุผลที่จะใช้ไม่มีและGetFiles()
GetDirectories()
Directory.Delete(path, true)
จะดูแลทุกคน :)
file.Delete()
คุณจำเป็นต้องเอาธงอ่านอย่างเดียวก่อนที่จะเรียก
ใช่นั่นเป็นวิธีที่ถูกต้องที่จะทำ หากคุณต้องการให้ "ล้าง" ด้วยตัวเอง (หรือตามที่ฉันต้องการเรียกว่า "ล้างข้อมูล" ฟังก์ชั่น) คุณสามารถสร้างวิธีการขยายได้
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);
}
นี้จะช่วยให้คุณทำสิ่งที่ชอบ ..
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(@"C:\...");
directory.Empty();
Empty
มีอยู่ใน C # string
แล้วสำหรับ ถ้าฉันเห็นสิ่งอื่นที่ชื่อEmpty
ฉันจะแปลกใจถ้ามันแก้ไขวัตถุ (หรือระบบแฟ้ม) แทนที่จะให้ฉันbool
ที่บอกว่ามันว่างเปล่าหรือไม่ Clean
เพราะการที่ฉันจะไปกับชื่อ
Is
(เช่นIsEmpty
มากกว่าEmpty
)
รหัสต่อไปนี้จะล้างโฟลเดอร์ซ้ำ:
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);
Delete
จะโยนถ้าไม่มีไดเรกทอรีอยู่ดังนั้นจะปลอดภัยกว่าถ้าทำการDirectory.Exists
ตรวจสอบก่อน
Directory.Exists
ยังไม่พอ หลังจากตรวจสอบเธรดอื่นอาจเปลี่ยนชื่อหรือลบไดเรกทอรี try-catch
มันเป็นความปลอดภัยในการ
Directory.Create
เพราะ recursive Directory.Delete
น่าเสียดายที่ไม่รับประกันว่าจะซิงโครนัส ..
เรายังสามารถแสดงความรักสำหรับ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));
โปรดทราบว่าวิธีการแก้ปัญหาของฉันที่นี่ไม่ได้เป็น performant เพราะฉันใช้Get*().ToList().ForEach(...)
ซึ่งสร้างIEnumerable
สองครั้งเดียวกัน ฉันใช้วิธีการขยายเพื่อหลีกเลี่ยงปัญหานี้:
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));
นี่คือวิธีการขยาย:
/// <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();
อาจมีการใช้งาน
directory.EnumerateFiles()
และdirectory.EnumerateDirectories()
แทนdirectory.Get*()
วิธีการต่างๆ
IEnumerable<T>.ForEach()
ส่วนขยายของฉันเองมีความคิดเห็น XML สรุป "การละเมิด! การละเมิด! ไม่สะอาด!"
วิธีที่ง่ายที่สุด:
Directory.Delete(path,true);
Directory.CreateDirectory(path);
โปรดระวังว่านี่อาจล้างสิทธิ์บางอย่างในโฟลเดอร์
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
}
}
หากคุณรู้ว่าไม่มีโฟลเดอร์ย่อยสิ่งนี้อาจเป็นวิธีที่ง่ายที่สุด:
Directory.GetFiles(folderName).ForEach(File.Delete)
System.IO.Directory.Delete(installPath, true);
System.IO.Directory.CreateDirectory(installPath);
ทุกวิธีที่ฉันลองพวกเขาล้มเหลวในบางจุดด้วยข้อผิดพลาด System.IO วิธีการต่อไปนี้ใช้งานได้อย่างแน่นอนแม้ว่าโฟลเดอร์จะว่างเปล่าหรือไม่เป็นแบบอ่านอย่างเดียวหรือไม่เป็นต้น
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);
นี่คือเครื่องมือที่ฉันลงท้ายด้วยหลังจากอ่านโพสต์ทั้งหมด มันทำ
มันเทียบกับ
มันไม่ได้ใช้ Directory.Delete เนื่องจากกระบวนการถูกยกเลิกในข้อยกเว้น
/// <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;
}
รหัสต่อไปนี้จะทำความสะอาดไดเรกทอรี แต่ปล่อยให้ไดเรกทอรีรากมี (เรียกซ้ำ)
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);
ฉันใช้
Directory.GetFiles(picturePath).ToList().ForEach(File.Delete);
สำหรับลบรูปภาพเก่าและฉันไม่ต้องการวัตถุใด ๆ ในโฟลเดอร์นี้
การใช้วิธีการคงที่กับไฟล์และไดเรกทอรีแทน FileInfo และ DirectoryInfo จะทำงานได้เร็วขึ้น (ดูคำตอบที่ยอมรับได้ที่ความแตกต่างระหว่างไฟล์และ FileInfo ใน C # คืออะไร ) คำตอบที่แสดงเป็นวิธีอรรถประโยชน์
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);
}
}
private void ClearFolder(string FolderName)
{
DirectoryInfo dir = new DirectoryInfo(FolderName);
foreach (FileInfo fi in dir.GetFiles())
{
fi.IsReadOnly = false;
fi.Delete();
}
foreach (DirectoryInfo di in dir.GetDirectories())
{
ClearFolder(di.FullName);
di.Delete();
}
}
string directoryPath = "C:\Temp";
Directory.GetFiles(directoryPath).ToList().ForEach(File.Delete);
Directory.GetDirectories(directoryPath).ToList().ForEach(Directory.Delete);
ใน Windows 7 หากคุณเพิ่งสร้างขึ้นเองด้วย Windows Explorer โครงสร้างไดเรกทอรีจะคล้ายกับอันนี้:
C:
\AAA
\BBB
\CCC
\DDD
และเรียกใช้รหัสที่แนะนำในคำถามเดิมเพื่อล้างไดเรกทอรี C: \ AAA บรรทัดdi.Delete(true)
ล้มเหลวเสมอกับ IOException "ไดเรกทอรีไม่ว่าง" เมื่อพยายามลบ BBB อาจเป็นเพราะความล่าช้า / การแคชบางอย่างใน Windows Explorer
รหัสต่อไปนี้ทำงานได้อย่างน่าเชื่อถือสำหรับฉัน:
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);
}
}
รุ่นนี้ไม่ได้ใช้การโทรซ้ำและแก้ไขปัญหาแบบอ่านอย่างเดียว
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();
}
}
ใช้วิธี GetDirectories ของ DirectoryInfo
foreach (DirectoryInfo subDir in new DirectoryInfo(targetDir).GetDirectories())
subDir.Delete(true);
ตัวอย่างต่อไปนี้แสดงวิธีการทำเช่นนั้น มันสร้างไดเรกทอรีและไฟล์บางส่วนก่อนแล้วจึงลบออกผ่าน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);
}
}
มันจะนำมาจากhttps://msdn.microsoft.com/en-us/library/fxeahc5f(v=vs.110).aspx
ไม่ใช่วิธีที่ดีที่สุดในการจัดการกับปัญหาข้างต้น แต่มันเป็นอีกทางเลือกหนึ่ง ...
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();
}
นี่จะแสดงวิธีที่เราลบโฟลเดอร์และตรวจสอบว่าเราใช้กล่องข้อความ
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);
โทรจากหลัก
static void Main(string[] args)
{
string Filepathe =<Your path>
DeleteDirectory(System.IO.Directory.GetParent(Filepathe).FullName);
}
เพิ่มวิธีนี้
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);
}
}
foreach (string file in System.IO.Directory.GetFiles(path))
{
System.IO.File.Delete(file);
}
foreach (string subDirectory in System.IO.Directory.GetDirectories(path))
{
System.IO.Directory.Delete(subDirectory,true);
}
หากต้องการลบโฟลเดอร์นี่คือรหัสโดยใช้กล่องข้อความและปุ่ม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
สิ่งเดียวที่คุณควรทำคือการตั้งค่าไปoptional recursive parameter
True
Directory.Delete("C:\MyDummyDirectory", True)
ขอบคุณ. NET :)
IO.Directory.Delete(HttpContext.Current.Server.MapPath(path), True)
คุณไม่ต้องการมากกว่านั้น