Wie erstelle ich eine Datei UND Ordner, wenn die Ordner nicht vorhanden sind?

136

Stellen Sie sich vor, ich möchte die folgende Datei erstellen (oder überschreiben): - C:\Temp\Bar\Foo\Test.txt

Verwendung der File.Create (..) -Methode kann dies geschehen .

ABER, wenn ich keinen der folgenden Ordner habe (von diesem Beispielpfad oben)

  • Temp
  • Bar
  • Foo

dann bekomme ich eine DirectoryNotFoundException ausgelöst.

Also .. gegeben ein Weg, wie können wir alle die Ordner rekursiv erstellen notwendig , um die Datei zu erstellen .. für diesen Pfad? Wenn temporäre oder Balkenordner vorhanden sind, Foo jedoch nicht ... dann wird dies ebenfalls erstellt.

Nehmen wir zur Vereinfachung an, dass keine Sicherheitsbedenken bestehen - alle Berechtigungen sind in Ordnung usw.

Pure.Krome
quelle

Antworten:

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

Siehe diese MSDN-Seite .

Hoffe das hilft!

Christopher B. Adkins
quelle
82
Sie können blind Directory.CreateDirectoryohne Directory.ExistsPrüfung anrufen - es wird nicht ausgelöst, wenn das Verzeichnis bereits vorhanden ist.
Tim Robinson
1
@ Tim: Ich war mir nicht sicher, also habe ich es da reingeworfen. Danke für die Info.
Christopher B. Adkins
24
Und vergessen Sie nicht Path.GetDirectoryName(string path), das Verzeichnis von Ihrem vollständigen Pfad zu erhalten
Oliver
@Oliver: Es gibt eine ganze Reihe von Funktionen, die mit den Klassen Directory und DirectoryInfo einhergehen, aber der Code, den ich gegeben habe, hat ausgereicht, um ihn in die richtige Richtung zu treiben. Ich denke, der Link erweitert sich auch ziemlich.
Christopher B. Adkins
8
* HINWEIS: Die Variable pathsollte nicht den Dateinamen enthalten. So pathsollte das Beispiel des OP sein C:\Temp\Bar\Foo. Nach dem Aufruf müssen Directory.CreateDirectory(path);Sie noch anrufen File.Create("C:\Temp\Bar\Foo\Test.txt");, um die Datei zu erstellen.
Sazr
139

Um zusammenzufassen, was in anderen Antworten kommentiert wurde:

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

Directory.CreateDirectory erstellt die Verzeichnisse rekursiv und wenn das Verzeichnis bereits vorhanden ist, wird es ohne Fehler zurückgegeben.

Wenn es passiert eine Datei sein Fooauf C:\Temp\Bar\Fooeine Ausnahme wird geworfen werden.

hultqvist
quelle
Wenn Sie mit langen Pfaden (256+) zu tun haben,
Alexei Levenkov
3

. Wie können wir bei gegebenem Pfad rekursiv alle Ordner erstellen, die zum Erstellen der Datei erforderlich sind?

Erstellt alle Verzeichnisse und Unterverzeichnisse wie im Pfad angegeben.

Directory.CreateDirectory(path);

Dann können Sie eine Datei erstellen.

Arseny
quelle
2
Pfad ohne Dateinamen :)
Sameera R.
"Alle Verzeichnisse und Unterverzeichnisse" Falsch: Es werden höchstens ein Verzeichnis und alle erforderlichen Unterverzeichnisse erstellt.
Camilo Terevinto
3

Sie müssen beide Teile des Pfads (Verzeichnis und Dateiname) überprüfen und jeden erstellen, wenn er nicht vorhanden ist.

Verwenden Sie File.Existsund Directory.Exists, um herauszufinden, ob sie existieren. Directory.CreateDirectoryerstellt den gesamten Pfad für Sie, sodass Sie diesen nur einmal aufrufen müssen, wenn das Verzeichnis nicht vorhanden ist, und dann einfach die Datei erstellen.

Oded
quelle
Für Directory.CreateDirectory müssen Sie nicht sehen, welcher Teil vorhanden ist. Es werden alle benötigten Verzeichnisse erstellt (nur um sicherzustellen, dass das Zielverzeichnis noch nicht vorhanden ist).
Gertjan
Ich schlage vor, in diesem Fall die erste Zeile Ihrer Antwort zu entfernen, da er nicht jedes Teil aus dem Stammverzeichnis überprüfen muss. Überprüfen Sie einfach den vollständigen Pfad und erstellen Sie ihn, falls er nicht vorhanden ist.
Gertjan
@Gertjan - Antwort aktualisiert ... hoffe, es entspricht jetzt Ihren Standards;)
Oded
:) es tut :) (es war nicht mein Punkt, Sie falsch zu beweisen oder Sie zu beleidigen, aber Anfänger können jede Klarstellung in den Antworten verwenden)
Gertjan
0

Sie möchten Directory.CreateDirectory ()

Hier ist eine Klasse, die ich verwende (konvertiert in C #). Wenn Sie ihr ein Quellverzeichnis und ein Ziel übergeben, werden alle Dateien und Unterordner dieses Verzeichnisses in Ihr Ziel kopiert:

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

}

}}

Markiv
quelle
2
Ich sollte dies wegen dieser Zeile herabstufen: using Microsoft.VisualBasic;Böse !!
Pure.Krome
2
Und warum ist Microsoft.VisualBasic böse? Es ist eine Assembly wie jeder andere im .Net Framework.
Oliver
2
Ich nehme an, weil Sie den Namespace einer ganz anderen Sprache unnötig importieren ..?
Markive
0

Angenommen, Ihre Assembly / Exe hat selbst die FileIO- Berechtigung, ist nicht richtig. Ihre Anwendung wird möglicherweise nicht mit Administratorrechten ausgeführt. Es ist wichtig, die Codezugriffssicherheit zu berücksichtigen und Berechtigungen anzufordern. Beispielcode:

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

Grundlegendes zur .NET-Codezugriffssicherheit

Ist "Code Access Security" von realer Bedeutung?

PRR
quelle
1
@ Pure.Krome: Obwohl meine Antwort nicht zielgerichtet ist, sollten Sie beim Zugriff auf privilegierte Ressourcen die Sicherheit und Zugriffskontrolle berücksichtigen. Nie beabsichtigt, Ihre Frage zu überholen oder zu komplizieren :)
PRR
0

Ich weiß, dass es hier einige andere Antworten gibt, aber keine davon ist nicht vollständig genug. Der folgende Code erstellt Verzeichnisse (falls nicht vorhanden) und kopiert dann Dateien .

// 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
quelle