178

Imagine I wish to create (or overwrite) the following file :- C:\Temp\Bar\Foo\Test.txt

Using the File.Create(..) method, this can do it.

BUT, if I don't have either one of the following folders (from that example path, above)

  • Temp
  • Bar
  • Foo

then I get an DirectoryNotFoundException thrown.

So .. given a path, how can we recursively create all the folders necessary to create the file .. for that path? If Temp or Bar folders exists, but Foo doesn't... then that is created also.

For simplicity, lets assume there's no Security concerns -- all permissions are fine, etc.

3

9 Answers 9

191

To summarize what has been commented in other answers:

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

Directory.CreateDirectory will create the directories recursively and if the directory already exist it will return without an error.

If there happened to be a file Foo at C:\Temp\Bar\Foo an exception will be thrown.

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

See this MSDN page.

6
  • 90
    You can blindly call Directory.CreateDirectory without the Directory.Exists check first - it won't throw if the directory is already there. Commented Jul 8, 2010 at 8:14
  • 1
    @Tim: Wasn't sure so I threw it in there anywho. Thanks for the info though. Commented Jul 8, 2010 at 8:16
  • 28
    And don't forget about Path.GetDirectoryName(string path) to get the directory from your full path
    – Oliver
    Commented Jul 8, 2010 at 8:21
  • @Oliver: There is a whole slew of functionality that goes along with the Directory and DirectoryInfo classes, but the code I gave was enough to give him a push in the right direction. I think the link also expands quite a bit. Commented Jul 8, 2010 at 9:12
  • 10
    *NOTE: the variable path should not contain the file name. So using the OP's example path should be C:\Temp\Bar\Foo. After calling Directory.CreateDirectory(path); you still need to call File.Create("C:\Temp\Bar\Foo\Test.txt"); to create the file.
    – sazr
    Commented Jun 25, 2014 at 5:45
17

Use Directory.CreateDirectory before you create the file. It creates the folder recursively for you.

0
5

. given a path, how can we recursively create all the folders necessary to create the file .. for that path

Creates all directories and subdirectories as specified by path.

Directory.CreateDirectory(path);

then you may create a file.

2
  • 2
    path without file name :)
    – Sameera R.
    Commented Feb 10, 2016 at 12:09
  • 1
    "all directories and subdirectiories" Incorrect: it will create, at most, one directory and all the required subdirectories. Commented Jun 17, 2016 at 15:09
4

You will need to check both parts of the path (directory and filename) and create each if it does not exist.

Use File.Exists and Directory.Exists to find out whether they exist. Directory.CreateDirectory will create the whole path for you, so you only ever need to call that once if the directory does not exist, then simply create the file.

4
  • For Directory.CreateDirectory you do not need to see which part exists. It will create all directories needed (only thing to make sure is that the targeted directory does not exists already).
    – Gertjan
    Commented Jul 8, 2010 at 8:02
  • I suggest removing the first line of you answer in that case since he doesn't need to check for each part from the root, just check the complete path and create it if it does not exist.
    – Gertjan
    Commented Jul 8, 2010 at 8:13
  • @Gertjan - answer updated... hope it meets your standards now ;)
    – Oded
    Commented Jul 8, 2010 at 8:18
  • :) it does :) (it was not my point to prove you wrong or to offend you, but beginners can use any clarification in the answers)
    – Gertjan
    Commented Jul 8, 2010 at 8:29
2

You should use Directory.CreateDirectory.

http://msdn.microsoft.com/en-us/library/54a0at6s.aspx

1
  • Remarks: Any and all directories specified in path are created ... ahh kewl! cheers :)
    – Pure.Krome
    Commented Jul 8, 2010 at 7:59
1

Assuming that your assembly/exe has FileIO permission is itself, well is not right. Your application may not run with admin rights. Its important to consider Code Access Security and requesting permissions Sample code:

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

Understanding .NET Code Access Security

Is “Code Access Security” of any real world use?

1
  • 2
    @Pure.Krome: Although my answer is off target, still do consider security and access control when accessing privileged resource. Never meant to overtake or complicate your question :)
    – PRR
    Commented Jul 9, 2010 at 5:15
0

You want Directory.CreateDirectory()

Here is a class I use (converted to C#) that if you pass it a source directory and a destination it will copy all of the files and sub-folders of that directory to your destination:

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

}

}

3
  • 3
    I should downgrade this because of this line: using Microsoft.VisualBasic; Evil!!
    – Pure.Krome
    Commented Jul 8, 2010 at 8:01
  • 2
    And why is Microsoft.VisualBasic evil?? It's an assembly like anyone else in the .Net Framework.
    – Oliver
    Commented Jul 8, 2010 at 8:20
  • 2
    I suppose because your importing the namespace of a whole other language unnecessarily..?
    – Markive
    Commented Jul 8, 2010 at 8:37
0

Following code will create directories (if not exists) & then copy files.

// 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"));
        }
    }
}
3
  • It seems like the questioner wanted to create files rather than copy them. Commented Jan 31, 2021 at 11:45
  • @ThomasFritz you are right, but still there some good info about working with files and folders in my answer, don't you think so? should I delete my answer? Commented Jan 31, 2021 at 15:53
  • I don't think you have to delete your answer per se: While it may not answer the original question it is placed below a handful of answers which do just that. Instead, your answer serves as an introduction to a different topic, specifically how files are copied, which I don't mind a little variety among StackOverflow answers. What you can do - if you have the time - is to adjust the wording of your answer in a way so that it doesn't present itself like the most complete answer of them all, which I believe to be an overstatement. Commented Feb 1, 2021 at 18:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.