Comment créer un fichier ET des dossiers, si les dossiers n'existent pas?

136

Imaginez que je souhaite créer (ou écraser) le fichier suivant: - C:\Temp\Bar\Foo\Test.txt

En utilisant la méthode File.Create (..) , cela peut le faire.

MAIS, si je n'ai aucun des dossiers suivants (à partir de cet exemple de chemin, ci-dessus)

  • Temp
  • Bar
  • Foo

puis j'obtiens une DirectoryNotFoundException lancée.

Alors .. étant donné un chemin, comment pouvons-nous créer récursivement tous les dossiers nécessaires pour créer le fichier .. pour ce chemin? Si des dossiers Temp ou Bar existent, mais pas Foo ... alors cela est également créé.

Pour plus de simplicité, supposons qu'il n'y a pas de problèmes de sécurité - toutes les autorisations sont correctes, etc.

Pure.Krome
la source
Copie possible de Si un dossier n'existe pas, créez-le
Michael Freidgeim

Réponses:

122
DirectoryInfo di = Directory.CreateDirectory(path);
Console.WriteLine("The directory was created successfully at {0}.",
    Directory.GetCreationTime(path));

Consultez cette page MSDN .

J'espère que cela aide!

Christopher B. Adkins
la source
82
Vous pouvez appeler à l'aveuglette Directory.CreateDirectorysans Directory.Existsvérification préalable - il ne sera pas lancé si le répertoire est déjà là.
Tim Robinson
1
@Tim: J'étais pas sûr, alors je l'ai jeté là-dedans n'importe qui. Merci néanmoins pour l'info.
Christopher B.Adkins
24
Et n'oubliez pas Path.GetDirectoryName(string path)d'obtenir le répertoire à partir de votre chemin complet
Oliver
@Oliver: Il y a toute une série de fonctionnalités qui accompagnent les classes Directory et DirectoryInfo, mais le code que j'ai donné était suffisant pour lui donner un coup de pouce dans la bonne direction. Je pense que le lien se développe également un peu.
Christopher B.Adkins
8
* REMARQUE: la variable pathne doit pas contenir le nom du fichier. Donc, en utilisant l'exemple de l'OP pathdevrait être C:\Temp\Bar\Foo. Après avoir appelé, Directory.CreateDirectory(path);vous devez toujours appeler File.Create("C:\Temp\Bar\Foo\Test.txt");pour créer le fichier.
sazr
139

Pour résumer ce qui a été commenté dans d'autres réponses:

//path = @"C:\Temp\Bar\Foo\Test.txt";
Directory.CreateDirectory(Path.GetDirectoryName(path));

Directory.CreateDirectory créera les répertoires de manière récursive et si le répertoire existe déjà, il retournera sans erreur.

S'il y a eu un fichier Fooà C:\Temp\Bar\Fooune exception sera levée.

hultqvist
la source
Si vous avez affaire à un long chemin (256+), voir stackoverflow.com/questions/5188527/…
Alexei Levenkov
3

. étant donné un chemin, comment pouvons-nous créer récursivement tous les dossiers nécessaires pour créer le fichier .. pour ce chemin

Crée tous les répertoires et sous-répertoires comme spécifié par chemin.

Directory.CreateDirectory(path);

alors vous pouvez créer un fichier.

Arseny
la source
2
chemin sans nom de fichier :)
Sameera R.
1
"tous les répertoires et sous-répertoires" Incorrect: cela créera, au maximum, un répertoire et tous les sous-répertoires requis.
Camilo Terevinto
3

Vous devrez vérifier les deux parties du chemin (répertoire et nom de fichier) et créer chacune si elle n'existe pas.

Utilisez File.Existset Directory.Existspour savoir s'ils existent. Directory.CreateDirectorycréera le chemin complet pour vous, vous n'aurez donc besoin de l'appeler qu'une seule fois si le répertoire n'existe pas, puis créez simplement le fichier.

Oded
la source
Pour Directory.CreateDirectory, vous n'avez pas besoin de voir quelle partie existe. Il créera tous les répertoires nécessaires (la seule chose à s'assurer est que le répertoire ciblé n'existe pas déjà).
Gertjan
Je suggère de supprimer la première ligne de votre réponse dans ce cas, car il n'a pas besoin de vérifier chaque partie à partir de la racine, vérifiez simplement le chemin complet et créez-le s'il n'existe pas.
Gertjan
@Gertjan - réponse mise à jour ... j'espère qu'elle répondra à vos normes maintenant;)
Oded
:) ça fait :) (ce n'était pas mon propos de vous prouver le contraire ou de vous offenser, mais les débutants peuvent utiliser n'importe quelle clarification dans les réponses)
Gertjan
0

Vous voulez Directory.CreateDirectory ()

Voici une classe que j'utilise (convertie en C #) que si vous lui passez un répertoire source et une destination, elle copiera tous les fichiers et sous-dossiers de ce répertoire vers votre destination:

using System.IO;

public class copyTemplateFiles
{


public static bool Copy(string Source, string destination)
{

    try {

        string[] Files = null;

        if (destination[destination.Length - 1] != Path.DirectorySeparatorChar) {
            destination += Path.DirectorySeparatorChar;
        }

        if (!Directory.Exists(destination)) {
            Directory.CreateDirectory(destination);
        }

        Files = Directory.GetFileSystemEntries(Source);
        foreach (string Element in Files) {
            // Sub directories
            if (Directory.Exists(Element)) {
                copyDirectory(Element, destination + Path.GetFileName(Element));
            } else {
                // Files in directory
                File.Copy(Element, destination + Path.GetFileName(Element), true);
            }
        }

    } catch (Exception ex) {
        return false;
    }

    return true;

}



private static void copyDirectory(string Source, string destination)
{
    string[] Files = null;

    if (destination[destination.Length - 1] != Path.DirectorySeparatorChar) {
        destination += Path.DirectorySeparatorChar;
    }

    if (!Directory.Exists(destination)) {
        Directory.CreateDirectory(destination);
    }

    Files = Directory.GetFileSystemEntries(Source);
    foreach (string Element in Files) {
        // Sub directories
        if (Directory.Exists(Element)) {
            copyDirectory(Element, destination + Path.GetFileName(Element));
        } else {
            // Files in directory
            File.Copy(Element, destination + Path.GetFileName(Element), true);
        }
    }

}

}

Markive
la source
2
Je devrais déclasser ceci à cause de cette ligne: using Microsoft.VisualBasic;Evil !!
Pure.Krome
2
Et pourquoi Microsoft.VisualBasic est-il mal? C'est un assemblage comme n'importe qui dans le .Net Framework.
Oliver
2
Je suppose que vous importez inutilement l'espace de noms d'un tout autre langage ..?
Markive
0

En supposant que votre assembly / exe a l' autorisation FileIO est lui-même, ce n'est pas bien. Votre application peut ne pas fonctionner avec les droits d'administrateur. Il est important de prendre en compte la sécurité d'accès au code et de demander des autorisations Exemple de code:

FileIOPermission f2 = new FileIOPermission(FileIOPermissionAccess.Read, "C:\\test_r");
f2.AddPathList(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, "C:\\example\\out.txt");
try
{
    f2.Demand();
}
catch (SecurityException s)
{
    Console.WriteLine(s.Message);
}

Comprendre la sécurité d'accès au code .NET

La «sécurité d'accès au code» est-elle d'une utilité réelle?

PRR
la source
1
@ Pure.Krome: Bien que ma réponse soit hors cible, pensez toujours à la sécurité et au contrôle d'accès lors de l'accès à une ressource privilégiée. Jamais voulu dépasser ou compliquer votre question :)
PRR
0

Je sais qu'il y a d'autres réponses ici, mais aucune d'entre elles n'est pas assez complète, le code suivant créera des répertoires (s'il n'existe pas) et copiera ensuite les fichiers .

// using System.IO;

// for ex. if you want to copy files from D:\A\ to D:\B\
foreach (var f in Directory.GetFiles(@"D:\A\", "*.*", SearchOption.AllDirectories))
{
    var fi =  new FileInfo(f);
    var di = new DirectoryInfo(fi.DirectoryName);

    // you can filter files here
    if (fi.Name.Contains("FILTER")
    {
        if (!Directory.Exists(di.FullName.Replace("A", "B"))
        {                       
            Directory.CreateDirectory(di.FullName.Replace("A", "B"));           
            File.Copy(fi.FullName, fi.FullName.Replace("A", "B"));
        }
    }
}
Mehdi Dehghani
la source