Sử dụng C #, làm cách nào tôi có thể xóa tất cả các tệp và thư mục khỏi một thư mục, nhưng vẫn giữ thư mục gốc?
Sử dụng C #, làm cách nào tôi có thể xóa tất cả các tệp và thư mục khỏi một thư mục, nhưng vẫn giữ thư mục gốc?
Câu trả lời:
System.IO.DirectoryInfo di = new DirectoryInfo("YourPath");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
Nếu thư mục của bạn có thể có nhiều tệp, EnumerateFiles()
hiệu quả hơn GetFiles()
, vì khi bạn sử dụng, EnumerateFiles()
bạn có thể bắt đầu liệt kê nó trước khi toàn bộ bộ sưu tập được trả về, trái ngược với GetFiles()
nơi bạn cần tải toàn bộ bộ sưu tập trong bộ nhớ trước khi bắt đầu liệt kê nó. Xem báo giá này ở đây :
Do đó, khi bạn đang làm việc với nhiều tệp và thư mục, Enum CảFiles () có thể hiệu quả hơn.
Điều tương tự áp dụng cho EnumerateDirectories()
và GetDirectories()
. Vì vậy, mã sẽ là:
foreach (FileInfo file in di.EnumerateFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.EnumerateDirectories())
{
dir.Delete(true);
}
Đối với mục đích của câu hỏi này, thực sự không có lý do để sử dụng GetFiles()
và GetDirectories()
.
Directory.Delete(path, true)
sẽ chăm sóc tất cả :)
file.Delete()
.
Vâng, đó là cách chính xác để làm điều đó. Nếu bạn đang tìm cách cung cấp cho mình một chức năng "Sạch" (hoặc, như tôi muốn gọi nó là chức năng "Làm trống"), bạn có thể tạo một phương thức mở rộng.
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);
}
Điều này sau đó sẽ cho phép bạn làm một cái gì đó như ..
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(@"C:\...");
directory.Empty();
Empty
tồn tại trong C #, cho string
. Nếu tôi thấy một cái gì đó khác có tên Empty
tôi sẽ ngạc nhiên nếu nó sửa đổi đối tượng (hoặc hệ thống tập tin) thay vì đưa cho tôi một thông bool
báo cho biết nó có trống hay không. Vì điều đó, tôi sẽ đi với cái tên Clean
.
Is
(nghĩa IsEmpty
là hơn Empty
).
Đoạn mã sau sẽ xóa thư mục đệ quy:
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
sẽ ném nếu thư mục không tồn tại, vì vậy sẽ an toàn hơn khi Directory.Exists
kiểm tra trước.
Directory.Exists
là không đủ; sau khi kiểm tra, một luồng khác có thể đã đổi tên hoặc xóa thư mục. Nó là an toàn hơn try-catch
.
Directory.Create
vì đệ quy Directory.Delete
không may không được đảm bảo là đồng bộ ..
Chúng tôi cũng có thể thể hiện tình yêu dành cho 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));
Lưu ý rằng giải pháp của tôi ở đây không phải là hiệu suất, bởi vì tôi đang sử dụng Get*().ToList().ForEach(...)
mà tạo ra IEnumerable
hai lần giống nhau . Tôi sử dụng một phương pháp mở rộng để tránh vấn đề này:
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));
Đây là phương pháp mở rộng:
/// <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();
có thể sẽ được sử dụng.
directory.EnumerateFiles()
và directory.EnumerateDirectories()
thay vì các directory.Get*()
phương pháp.
IEnumerable<T>.ForEach()
tiện ích mở rộng của riêng tôi có một nhận xét XML tóm tắt, "Vi phạm! Vi phạm! Ô uế!".
Cách đơn giản nhất:
Directory.Delete(path,true);
Directory.CreateDirectory(path);
Hãy lưu ý rằng điều này có thể xóa sạch một số quyền trên thư mục.
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
}
}
Nếu bạn biết không có thư mục con, một cái gì đó như thế này có thể là dễ nhất:
Directory.GetFiles(folderName).ForEach(File.Delete)
Mọi phương pháp mà tôi đã thử, chúng đều thất bại tại một số điểm với lỗi System.IO. Phương pháp sau đây hoạt động chắc chắn, ngay cả khi thư mục có trống hay không, chỉ đọc hoặc không, v.v.
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);
Đây là công cụ tôi đã kết thúc sau khi đọc tất cả các bài viết. Nó làm
Nó liên quan đến
Nó không sử dụng Directory.Delete vì quá trình bị hủy bỏ ngoại lệ.
/// <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;
}
Đoạn mã sau sẽ dọn sạch thư mục, nhưng để lại thư mục gốc ở đó (đệ quy).
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);
Tôi đã sử dụng
Directory.GetFiles(picturePath).ToList().ForEach(File.Delete);
để xóa ảnh cũ và tôi không cần bất kỳ đối tượng nào trong thư mục này
Chỉ sử dụng các phương thức tĩnh với Tệp và Thư mục thay vì FileInfo và DirectoryInfo sẽ thực hiện nhanh hơn. (xem câu trả lời được chấp nhận tại Sự khác biệt giữa File và FileInfo trong C # là gì? ). Trả lời hiển thị như phương pháp tiện ích.
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);
Trong Windows 7, nếu bạn vừa tạo thủ công với Windows Explorer, cấu trúc thư mục tương tự như cấu trúc này:
C:
\AAA
\BBB
\CCC
\DDD
Và chạy mã được đề xuất trong câu hỏi ban đầu để xóa thư mục C: \ AAA, dòng di.Delete(true)
luôn bị lỗi với IOException "Thư mục không trống" khi cố gắng xóa BBB. Có lẽ là do một số loại chậm trễ / bộ nhớ đệm trong Windows Explorer.
Các mã sau hoạt động đáng tin cậy cho tôi:
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);
}
}
Phiên bản này không sử dụng các cuộc gọi đệ quy và giải quyết vấn đề chỉ đọc.
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();
}
}
Ví dụ sau đây cho thấy cách bạn có thể làm điều đó. Đầu tiên, nó tạo một số thư mục và một tệp và sau đó xóa chúng thông qua 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);
}
}
Nó được lấy từ https://msdn.microsoft.com/en-us/l Library / fxeahc5f (v = vs.110) .aspx .
Đây không phải là cách tốt nhất để giải quyết vấn đề trên. Nhưng đó là một thay thế ...
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();
}
Điều này sẽ cho thấy cách chúng tôi xóa thư mục và kiểm tra xem chúng tôi sử dụng Hộp văn bản
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);
Gọi từ chính
static void Main(string[] args)
{
string Filepathe =<Your path>
DeleteDirectory(System.IO.Directory.GetParent(Filepathe).FullName);
}
Thêm phương pháp này
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);
}
}
Để xóa thư mục, đây là mã bằng hộp Văn bản và một nút 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)
Bạn không cần nhiều hơn thế