Jak mogę utworzyć plik ORAZ dowolne foldery, jeśli foldery nie istnieją?

136

Wyobraź sobie, że chciałbym utworzyć (lub nadpisać) następujący plik: - C:\Temp\Bar\Foo\Test.txt

Można to zrobić przy użyciu metody File.Create (..) .

ALE, jeśli nie mam żadnego z następujących folderów (z tej przykładowej ścieżki powyżej)

  • Temp
  • Bar
  • bla

następnie otrzymuję zgłoszenie DirectoryNotFoundException .

Więc… mając ścieżkę, jak możemy rekurencyjnie utworzyć wszystkie foldery potrzebne do utworzenia pliku… dla tej ścieżki? Jeśli istnieją foldery Temp lub Bar, ale Foo nie ... to również jest tworzone.

Dla uproszczenia załóżmy, że nie ma obaw związanych z bezpieczeństwem - wszystkie uprawnienia są w porządku itp.

Pure.Krome
źródło
Możliwy duplikat Jeśli folder nie istnieje, utwórz go
Michael Freidgeim

Odpowiedzi:

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

Zobacz tę stronę MSDN .

Mam nadzieję, że to pomoże!

Christopher B. Adkins
źródło
82
Możesz dzwonić na ślepo Directory.CreateDirectorybez Directory.Existssprawdzenia najpierw - nie zostanie wyrzucony, jeśli katalog już tam jest.
Tim Robinson,
1
@Tim: Nie byłem pewien, więc wrzuciłem go tam gdziekolwiek. Dzięki za informację.
Christopher B. Adkins
24
I nie zapomnij o Path.GetDirectoryName(string path)pobraniu katalogu z pełnej ścieżki
Oliver
@Oliver: Istnieje cała masa funkcji, które towarzyszą klasom Directory i DirectoryInfo, ale kod, który podałem, wystarczył, aby popchnąć go we właściwym kierunku. Myślę, że link również trochę się rozszerza.
Christopher B. Adkins
8
* UWAGA: zmienna pathnie powinna zawierać nazwy pliku. Tak więc na przykładzie PO pathpowinno być C:\Temp\Bar\Foo. Po wywołaniu Directory.CreateDirectory(path);nadal musisz zadzwonić, File.Create("C:\Temp\Bar\Foo\Test.txt");aby utworzyć plik.
sazr
139

Podsumowując, co zostało skomentowane w innych odpowiedziach:

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

Directory.CreateDirectory utworzy katalogi rekurencyjnie i jeśli katalog już istnieje, zwróci bez błędu.

Jeśli zdarzyło się, że plik Foow C:\Temp\Bar\Foowyjątku zostanie wyrzucony.

hultqvist
źródło
Jeśli masz do czynienia z długą ścieżką (256+), zobacz stackoverflow.com/questions/5188527/…
Alexei Levenkov
3

. biorąc pod uwagę ścieżkę, w jaki sposób możemy rekurencyjnie utworzyć wszystkie foldery niezbędne do utworzenia pliku .. dla tej ścieżki

Tworzy wszystkie katalogi i podkatalogi określone przez ścieżkę.

Directory.CreateDirectory(path);

wtedy możesz stworzyć plik.

Arseny
źródło
2
ścieżka bez nazwy pliku :)
Sameera R.
„wszystkie katalogi i podkatalogi” Niepoprawnie: utworzy co najwyżej jeden katalog i wszystkie wymagane podkatalogi.
Camilo Terevinto
3

Będziesz musiał sprawdzić obie części ścieżki (katalog i nazwę pliku) i utworzyć każdą, jeśli nie istnieje.

Użyj File.Existsi, Directory.Existsaby dowiedzieć się, czy istnieją. Directory.CreateDirectoryutworzy dla ciebie całą ścieżkę, więc wystarczy wywołać ją tylko raz, jeśli katalog nie istnieje, a następnie po prostu utworzyć plik.

Oded
źródło
W przypadku Directory.CreateDirectory nie musisz sprawdzać, która część istnieje. Stworzy wszystkie potrzebne katalogi (jedyną rzeczą do upewnienia się, że katalog docelowy już nie istnieje).
Gertjan,
Proponuję usunąć pierwszą linię odpowiedzi w tym przypadku, ponieważ nie musi on sprawdzać każdej części z katalogu głównego, po prostu sprawdź pełną ścieżkę i utwórz ją, jeśli nie istnieje.
Gertjan,
@Gertjan - odpowiedź zaktualizowana ... mam nadzieję, że teraz spełnia twoje standardy;)
Oded
:) tak jest :) (nie chodziło mi o to, żeby ci udowodnić, że się mylisz lub urazić, ale początkujący mogą użyć dowolnego wyjaśnienia w odpowiedziach)
Gertjan
0

Chcesz Directory.CreateDirectory ()

Oto klasa, której używam (przekonwertowana na C #), która jeśli przekażesz jej katalog źródłowy i miejsce docelowe, skopiuje wszystkie pliki i podfoldery tego katalogu do twojego miejsca docelowego:

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
źródło
2
Powinienem obniżyć to z powodu tego wiersza: using Microsoft.VisualBasic;Zło !!
Pure.Krome,
2
A dlaczego Microsoft.VisualBasic jest zły? Jest to zespół jak każdy inny w .Net Framework.
Oliver
2
Przypuszczam, że niepotrzebnie importujesz przestrzeń nazw całego innego języka ..?
Markive
0

Zakładając, że twój assembler / exe ma uprawnienia FileIO , to nie jest w porządku. Twoja aplikacja może nie działać z uprawnieniami administratora. Ważne jest, aby wziąć pod uwagę bezpieczeństwo dostępu do kodu i żądanie uprawnień Przykładowy kod:

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

Zrozumienie zabezpieczeń dostępu do kodu .NET

Czy „bezpieczeństwo dostępu kodu” ma zastosowanie w prawdziwym świecie?

PRR
źródło
1
@ Pure.Krome: Chociaż moja odpowiedź jest niecelowa, nadal rozważ bezpieczeństwo i kontrolę dostępu podczas uzyskiwania dostępu do uprzywilejowanych zasobów. Nigdy nie chciałem wyprzedzać ani komplikować twojego pytania :)
PRR
0

Wiem, że są tu inne odpowiedzi, ale żadna z nich nie jest wystarczająco kompletna, następujący kod utworzy katalogi (jeśli nie istnieją), a następnie skopiuje pliki .

// 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
źródło