Come faccio a creare un file E eventuali cartelle, se le cartelle non esistono?


136

Immagina di voler creare (o sovrascrivere) il seguente file: - C:\Temp\Bar\Foo\Test.txt

Utilizzando il metodo File.Create (..) , questo può farlo.

MA, se non ho una delle seguenti cartelle (da quel percorso di esempio, sopra)

  • Temp
  • Bar
  • foo

poi mi viene lanciata una DirectoryNotFoundException .

Quindi .. dato un percorso, come possiamo creare ricorsivamente tutte le cartelle necessarie per creare il file .. per quel percorso? Se esistono cartelle Temp o Bar, ma Foo no ... allora anche quello viene creato.

Per semplicità, supponiamo che non ci siano problemi di sicurezza: tutte le autorizzazioni vanno bene, ecc.



Risposte:


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

Vedi questa pagina MSDN .

Spero che ti aiuti!


82
Puoi chiamare Directory.CreateDirectoryprima alla cieca senza il Directory.Existssegno di spunta: non verrà lanciato se la directory è già lì.
Tim Robinson,

1
@Tim: Non ero sicuro, quindi l'ho gettato lì dentro comunque. Grazie per le informazioni però.
Christopher B. Adkins

24
E non dimenticare Path.GetDirectoryName(string path)di ottenere la directory dal tuo percorso completo
Oliver

@Oliver: c'è un'intera serie di funzionalità che si accompagna alle classi Directory e DirectoryInfo, ma il codice che ho dato è stato sufficiente per dargli una spinta nella giusta direzione. Penso che anche il collegamento si espanda un po '.
Christopher B. Adkins,

8
* NOTA: la variabile pathnon deve contenere il nome del file. Quindi, usando l'esempio dell'OP pathdovrebbe essere C:\Temp\Bar\Foo. Dopo aver chiamato Directory.CreateDirectory(path);è ancora necessario chiamare File.Create("C:\Temp\Bar\Foo\Test.txt");per creare il file.
sabato

139

Per riassumere ciò che è stato commentato in altre risposte:

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

Directory.CreateDirectory creerà le directory in modo ricorsivo e se la directory esiste già, tornerà senza errori.

Se non v'è capitato di essere un file Fooa C:\Temp\Bar\Fooverrà generata un'eccezione.


Se avete a che fare con il percorso lungo (256 +) vedi stackoverflow.com/questions/5188527/...
Alexei Levenkov


3

. dato un percorso, come possiamo creare ricorsivamente tutte le cartelle necessarie per creare il file .. per quel percorso

Crea tutte le directory e le sottodirectory come specificato dal percorso.

Directory.CreateDirectory(path);

quindi è possibile creare un file.


2
percorso senza nome file :)
Sameera R.

1
"tutte le directory e le sottodirectory" Errato: creerà, al massimo, una directory e tutte le sottodirectory richieste.
Camilo Terevinto,

3

Dovrai controllare entrambe le parti del percorso (directory e nome file) e crearne ciascuna se non esiste.

Usa File.Existse Directory.Existsper scoprire se esistono. Directory.CreateDirectorycreerà l'intero percorso per te, quindi dovrai solo chiamarlo una volta sola se la directory non esiste, quindi semplicemente creare il file.


Per Directory.CreateDirectory non è necessario vedere quale parte esiste. Creerà tutte le directory necessarie (l'unica cosa da verificare è che la directory di destinazione non esiste già).
Gertjan,

Suggerisco di rimuovere la prima riga della tua risposta in quel caso poiché non ha bisogno di controllare ogni parte dalla radice, basta controllare il percorso completo e crearlo se non esiste.
Gertjan,

@Gertjan - risposta aggiornata ... spero che soddisfi i tuoi standard ora;)
Oded

:) lo fa :) (non era mio punto dimostrare che ti sbagli o offenderti, ma i principianti possono usare qualsiasi chiarimento nelle risposte)
Gertjan


0

Vuoi Directory.CreateDirectory ()

Ecco una classe che uso (convertita in C #) che se le passi una directory di origine e una destinazione copierà tutti i file e le sottocartelle di quella directory nella tua destinazione:

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

}

}


2
Dovrei effettuare il downgrade a causa di questa linea: using Microsoft.VisualBasic;Evil !!
Pure.Krome

2
E perché il male di Microsoft.VisualBasic ?? È un assembly come chiunque altro in .Net Framework.
Oliver,

2
Suppongo che stai importando inutilmente lo spazio dei nomi di un'intera altra lingua ...?
Markive

0

Supponendo che il tuo assembly / exe abbia l' autorizzazione FileIO è di per sé, non è giusto. La tua applicazione potrebbe non funzionare con i diritti di amministratore. È importante considerare la sicurezza dell'accesso al codice e richiedere autorizzazioni Codice di esempio:

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

Comprensione della sicurezza dell'accesso al codice .NET

"Code Access Security" di qualsiasi uso nel mondo reale?


1
@ Pure.Krome: Anche se la mia risposta non è target, tengo comunque conto della sicurezza e del controllo dell'accesso quando si accede a una risorsa privilegiata. Non ho mai avuto intenzione di superare o complicare la tua domanda :)
PRR

0

So che ci sono altre risposte qui, ma nessuna di queste non è abbastanza completa, il codice seguente creerà le directory (se non esiste) e quindi copierà i file .

// 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"));
        }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.