779 votes

Comment supprimer tous les fichiers et dossiers d'un répertoire ?

En utilisant C#, comment puis-je supprimer tous les fichiers et dossiers d'un répertoire, tout en conservant le répertoire racine ?

980voto

gsharp Points 4704
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 peut contenir 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 toute la collection en mémoire avant de commencer à l'énumérer. Voir cette citation aquí :

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() y GetDirectories() . Donc le code serait :

foreach (FileInfo file in di.EnumerateFiles())
{
    file.Delete(); 
}
foreach (DirectoryInfo dir in di.EnumerateDirectories())
{
    dir.Delete(true); 
}

Pour les besoins de cette question, il n'y a vraiment aucune raison d'utiliser GetFiles() y GetDirectories() .

2 votes

Appeler file.Delete() puis dir.Delete(true) est redondant puisque dir.Delete(true) supprime récursivement tous les fichiers et dossiers du répertoire spécifié. Le simple fait d'appeler di.Delete(true) évite d'avoir à utiliser deux boucles foreach : docs.microsoft.com/fr/us/dotnet/api/

2 votes

@NotoriousPyro l'utilisateur veut que le dossier racine soit conservé, c'est pourquoi les deux foreach

196voto

Adam Robinson Points 88472

Oui, c'est la bonne façon de faire. Si vous souhaitez vous doter d'une fonction "propre" (ou, comme je préfère 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();

83voto

hiteshbiblog Points 221

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();
    }
}

43voto

ThulasiRam Points 3795
 new System.IO.DirectoryInfo(@"C:\Temp").Delete(true);

 //Or

 System.IO.Directory.Delete(@"C:\Temp", true);

40voto

rasx Points 1858

Nous pouvons aussi montrer notre 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, parce que 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));

Il s'agit de 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);
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X