Как создать файл и любые папки, если папки не существуют?

136

Представьте, что я хочу создать (или перезаписать) следующий файл: - C:\Temp\Bar\Foo\Test.txt

Используя метод File.Create (..) , это можно сделать.

НО, если у меня нет ни одной из следующих папок (из этого примера, путь выше)

  • температура
  • Бар
  • Foo

тогда я получаю исключение DirectoryNotFoundException .

Итак ... учитывая путь, как мы можем рекурсивно создать все папки, необходимые для создания файла ... для этого пути? Если папки Temp или Bar существуют, а Foo нет ..., то они тоже создаются.

Для простоты предположим, что проблем безопасности нет - все разрешения в порядке и т. Д.

Pure.Krome
источник

Ответы:

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

Смотрите эту страницу MSDN .

Надеюсь, это поможет!

Кристофер Б. Адкинс
источник
82
Вы можете сначала слепо позвонить Directory.CreateDirectoryбез Directory.Existsчека - он не выдаст, если каталог уже существует.
Тим Робинсон
1
@ Тим: Не был уверен, поэтому я бросил это там, кто угодно. Спасибо за информацию, хотя.
Кристофер Б. Адкинс
24
И не забудьте Path.GetDirectoryName(string path)получить каталог с полным путем
Оливер
@ Оливер: Существует целый ряд функциональных возможностей, которые сочетаются с классами Directory и DirectoryInfo, но приведенного мною кода было достаточно, чтобы дать ему толчок в правильном направлении. Я думаю, что ссылка тоже немного расширяется.
Кристофер Б. Адкинс
8
* ПРИМЕЧАНИЕ: переменная pathне должна содержать имя файла. Таким образом, использование примера OP pathдолжно быть C:\Temp\Bar\Foo. После звонка Directory.CreateDirectory(path);вам все равно нужно позвонить, File.Create("C:\Temp\Bar\Foo\Test.txt");чтобы создать файл.
Сазр
139

Подводя итог тому, что было прокомментировано в других ответах:

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

Directory.CreateDirectory создаст каталоги рекурсивно, и если каталог уже существует, он вернется без ошибки.

Если случился файл, Fooв C:\Temp\Bar\Fooисключение будет брошено.

hultqvist
источник
Если вы имеете дело с длинным путем (256+) см stackoverflow.com/questions/5188527/...
Алексей Левенков
3

, учитывая путь, как мы можем рекурсивно создать все папки, необходимые для создания файла .. для этого пути

Создает все каталоги и подкаталоги, как указано путем.

Directory.CreateDirectory(path);

тогда вы можете создать файл.

Арсений
источник
2
путь без имени файла :)
Самера Р.
1
«все каталоги и подкаталоги» Неправильно: будет создано не более одного каталога и всех необходимых подкаталогов.
Камило Теревинто
3

Вам нужно будет проверить обе части пути (каталог и имя файла) и создать каждую, если она не существует.

Используйте File.Existsи, Directory.Existsчтобы узнать, существуют ли они. Directory.CreateDirectoryсоздаст полный путь для вас, так что вам нужно будет вызвать его только один раз, если каталог не существует, а затем просто создать файл.

Одед
источник
Для Directory.CreateDirectory вам не нужно видеть, какая часть существует. Он создаст все необходимые каталоги (единственное, что нужно сделать, это убедиться, что целевой каталог еще не существует).
Гертьян
В этом случае я предлагаю удалить первую строку вашего ответа, поскольку ему не нужно проверять каждую часть из корня, просто проверьте полный путь и создайте его, если он не существует.
Гертьян
@Gertjan - ответ обновлен ... надеюсь, что теперь он соответствует вашим стандартам;)
Одед
:) так и есть :) (я не собирался доказывать, что ты не прав или обидеть тебя, но новички могут использовать любые разъяснения в ответах)
Гертьян,
0

Вы хотите Directory.CreateDirectory ()

Вот класс, который я использую (преобразованный в C #): если вы передадите ему исходный каталог и место назначения, он скопирует все файлы и подпапки этого каталога в ваше место назначения:

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
источник
2
Я должен понизить это из-за этой строки: using Microsoft.VisualBasic;зло !!
Pure.Krome
2
И почему Microsoft.VisualBasic является злом ?? Это сборка, как и все остальные в .Net Framework.
Оливер
2
Я полагаю, потому что вы импортировали пространство имен целого другого языка без необходимости ..?
Маркив
0

Предполагать, что ваша сборка / exe имеет разрешение на FileIO само по себе, ну не правильно. Ваше приложение может не работать с правами администратора. Важно учитывать безопасность доступа к коду и запрашивать разрешения. Пример кода:

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

Понимание .NET Code Access Security

Используется ли «Code Access Security» в реальном мире?

ПРР
источник
1
@ Pure.Krome: хотя мой ответ не намечен, все же учитывайте безопасность и контроль доступа при доступе к привилегированному ресурсу. Никогда не хотел обгонять или усложнять ваш вопрос :)
PRR
0

Я знаю, что здесь есть некоторые другие ответы, но ни один из них не является достаточно полным, следующий код создаст каталоги (если не существует) и затем скопирует файлы .

// 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"));
        }
    }
}
Мехди Дехгани
источник