Як створити файл І будь-які папки, якщо папки не існують?


136

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

Використовуючи метод File.Create (..) , це можна зробити.

АЛЕ, якщо я не маю жодної із наведених нижче папок (із цього прикладу шляху вище)

  • Темп
  • Бар
  • Foo

то я отримую кинутий DirectoryNotFoundException .

Отже .. заданий шлях, як ми можемо рекурсивно створити всі папки, необхідні для створення файлу .. для цього шляху? Якщо папки Temp або Bar існують, але Foo немає ..., це також створено.

Для простоти припустимо, що немає проблем із безпекою - усі дозволи є нормальними тощо.



Відповіді:


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
@Tim: Не був впевнений, тому я кинув його туди, хто. Дякую за інформацію, хоча.
Крістофер Б. Адкінс

24
І не забудьте Path.GetDirectoryName(string path)отримати повний шлях до каталогу
Олівер

@Oliver: Існує ціла низка функціональних можливостей, яка поєднується з класами Directory та DirectoryInfo, але коду, який я дав, було достатньо, щоб дати йому поштовх у правильному напрямку. Я думаю, що посилання також сильно розширюється.
Крістофер Б. Адкінс

8
* ПРИМІТКА: змінна pathне повинна містити ім'я файлу. Тож, використовуючи приклад ОП, pathслід C:\Temp\Bar\Foo. Після дзвінка Directory.CreateDirectory(path);вам все одно потрібно зателефонувати, File.Create("C:\Temp\Bar\Foo\Test.txt");щоб створити файл.
sazr

139

Щоб підсумувати те, що було прокоментовано в інших відповідях:

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

Directory.CreateDirectory буде створювати каталоги рекурсивно, і якщо каталог вже існує, він повернеться без помилок.

Якщо трапився файл Fooза C:\Temp\Bar\Fooвинятком, буде викинуто.


Якщо ви маєте справу з довгим шляхом (256+) см stackoverflow.com/questions/5188527 / ...
Олексій Левенко


3

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

Створює всі каталоги та підкаталоги, як зазначено шляхом.

Directory.CreateDirectory(path);

тоді ви можете створити файл.


2
шлях без назви файлу :)
Sameera R.

"всі каталоги та підкаталоги" Неправильно: він створить, щонайменше, один каталог та всі необхідні підкаталоги.
Каміло Теревінто

3

Вам потрібно буде перевірити обидві частини шляху (каталог та ім’я файлу) та створити кожну, якщо її немає.

Використовуйте File.Existsта Directory.Existsз’ясовуйте, чи існують вони. Directory.CreateDirectoryстворить для вас весь шлях, тож вам потрібно коли-небудь зателефонувати, якщо каталог не існує, а потім просто створити файл.


Для Directory.CreateDirectory вам не потрібно бачити, яка частина існує. Він створить усі необхідні каталоги (єдине, що потрібно переконатись у тому, що цільовий каталог вже не існує).
Герт'ян

Я пропоную видалити перший відповідь у цьому випадку, оскільки йому не потрібно перевіряти кожну частину від кореня, просто перевірте повний шлях та створіть його, якщо його не існує.
Герт'ян

@Gertjan - відповідь оновлена ​​... сподіваюсь, що вона відповідає вашим стандартам зараз;)
Oded

:) це так :) (не було в мене сенсу доводити, що ви помиляєтесь, або ображати вас, але початківці можуть використовувати будь-яке уточнення у відповідях)
Гертян


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

}

}


2
Мені слід знизити це через цей рядок: using Microsoft.VisualBasic;Зло !!
Pure.Krome

2
І чому Microsoft.VisualBasic злий ?? Це збірка, як ніхто інший в .Net Framework.
Олівер

2
Я думаю, тому що ваш імпорт простору імен цілком іншої мови зайвим ..?
Markive

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 Security Security Access

Чи є «Кодова безпека доступу» будь-якого реального світу?


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"));
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.