Avec C #, comment puis-je supprimer tous les fichiers et dossiers d’un répertoire tout en conservant le répertoire racine?
System.IO.DirectoryInfo di = new DirectoryInfo("YourPath");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
Si votre répertoire contient de nombreux fichiers, EnumerateFiles()
est plus efficace que GetFiles()
, car lorsque vous utilisez EnumerateFiles()
, vous pouvez commencer à l'énumérer avant que la collection entière ne soit renvoyée, par opposition à GetFiles()
où vous devez charger l'intégralité de la collection en mémoire avant de commencer à énumérer. il. Voir cette citation ici :
Par conséquent, lorsque vous travaillez avec de nombreux fichiers et répertoires, EnumerateFiles () peut être plus efficace.
Il en va de même pour EnumerateDirectories()
et GetDirectories()
. Donc, le code serait:
foreach (FileInfo file in di.EnumerateFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.EnumerateDirectories())
{
dir.Delete(true);
}
Aux fins de cette question, il n'y a vraiment aucune raison d'utiliser GetFiles()
et GetDirectories()
.
Oui, c'est la bonne façon de le faire. Si vous souhaitez vous donner une fonction "Propre" (ou, comme je préfèrerais l'appeler, "vide"), vous pouvez créer une méthode d'extension.
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);
}
Cela vous permettra ensuite de faire quelque chose comme ..
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(@"C:\...");
directory.Empty();
Le code suivant effacera le dossier de manière récursive:
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);
Nous pouvons aussi montrer de l'amour pour 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));
Notez que ma solution ici n’est pas performante, car j’utilise Get*().ToList().ForEach(...)
qui génère le même IEnumerable
deux fois. J'utilise une méthode d'extension pour éviter ce problème:
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));
C'est la méthode d'extension:
/// <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);
}
}
}
Le moyen le plus simple:
Directory.Delete(path,true);
Directory.CreateDirectory(path);
Sachez que cela peut effacer certaines autorisations sur le dossier.
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
}
}
Si vous savez qu'il n'y a pas de sous-dossiers, c'est peut-être le plus simple:
Directory.GetFiles(folderName).ForEach(File.Delete)
System.IO.Directory.Delete(installPath, true);
System.IO.Directory.CreateDirectory(installPath);
Toutes les méthodes que j'ai essayées ont échoué à un moment donné avec des erreurs System.IO. La méthode suivante fonctionne à coup sûr, même si le dossier est vide ou non, en lecture seule ou non, etc.
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);
Le code suivant va nettoyer le répertoire, mais y laisser le répertoire racine (récursif).
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);
Voici l'outil avec lequel j'ai terminé après avoir lu tous les articles. Cela fait
Ça parle de
Il n'utilise pas Directory.Delete car le processus est abandonné à une exception.
/// <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;
}
Utiliser uniquement des méthodes statiques avec File and Directory au lieu de FileInfo et DirectoryInfo sera plus rapide. (Voir la réponse acceptée à l'étape Quelle est la différence entre File et FileInfo en C #? ). Réponse affichée comme méthode d'utilité.
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();
}
}
Sous Windows 7, si vous venez de le créer manuellement avec l'Explorateur Windows, la structure de répertoires est similaire à celle-ci:
C:
\AAA
\BBB
\CCC
\DDD
Et en exécutant le code suggéré dans la question d'origine pour nettoyer le répertoire C:\AAA, la ligne di.Delete(true)
échoue toujours avec IOException "Le répertoire n'est pas vide" lors de la tentative de suppression de BBB. Cela est probablement dû à une sorte de retard/mise en cache dans l'Explorateur Windows.
Le code suivant fonctionne de manière fiable pour moi:
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);
}
}
string directoryPath = "C:\Temp";
Directory.GetFiles(directoryPath).ToList().ForEach(File.Delete);
Directory.GetDirectories(directoryPath).ToList().ForEach(Directory.Delete);
Cette version n'utilise pas d'appels récursifs et résout le problème en lecture seule.
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();
}
}
Ce n'est pas la meilleure façon de traiter le problème ci-dessus. Mais c'est une alternative ...
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]);
}
utilisez la méthode GetDirectories de DirectoryInfo.
foreach (DirectoryInfo subDir in new DirectoryInfo(targetDir).GetDirectories())
subDir.Delete(true);
L'exemple suivant montre comment vous pouvez le faire. Il crée d’abord des répertoires et un fichier, puis les supprime via 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);
}
}
Il provient de https://msdn.Microsoft.com/en-us/library/fxeahc5f (v = vs.110) .aspx .
cela montrera comment nous supprimons le dossier et le vérifions, nous utilisons la zone de texte
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();
}
}
}
Pour supprimer le dossier, il s'agit d'un code utilisant une zone de texte et un bouton 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);
}
}
DirectoryInfo Folder = new DirectoryInfo(Server.MapPath(path));
if (Folder .Exists)
{
foreach (FileInfo fl in Folder .GetFiles())
{
fl.Delete();
}
Folder .Delete();
}
using System;
using System.IO;
namespace DeleteFoldersAndFilesInDirectory
{
class Program
{
public static void DeleteAll(string path)
{
string[] directories = Directory.GetDirectories(path);
string[] files = Directory.GetFiles(path);
foreach (string x in directories)
Directory.Delete(x, true);
foreach (string x in files)
File.Delete(x);
}
static void Main()
{
Console.WriteLine("Enter The Directory:");
string directory = Console.ReadLine();
Console.WriteLine("Deleting all files and directories ...");
DeleteAll(directory);
Console.WriteLine("Deleted");
}
}
}
using System.IO;
string[] filePaths = Directory.GetFiles(@"c:\MyDir\");
foreach (string filePath in filePaths)
File.Delete(filePath);
Appel du principal
static void Main(string[] args)
{
string Filepathe =<Your path>
DeleteDirectory(System.IO.Directory.GetParent(Filepathe).FullName);
}
Ajouter cette méthode
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);
}
J'ai utilisé
Directory.GetFiles(picturePath).ToList().ForEach(File.Delete);
pour supprimer l'ancienne photo et je n'ai besoin d'aucun objet dans ce dossier