How do I create a file AND any folders, if the folders don't exist?
Asked Answered
R

9

174

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.

Reed answered 8/7, 2010 at 7:51 Comment(3)
possible duplicate of saving a file and automatically create directoriesAkvavit
Possible duplicate of If a folder does not exist, create itHonorarium
Check this: codingfusion.com/Post/…Practiced
B
140
DirectoryInfo di = Directory.CreateDirectory(path);
Console.WriteLine("The directory was created successfully at {0}.",
    Directory.GetCreationTime(path));

See this MSDN page.

Belen answered 8/7, 2010 at 7:56 Comment(6)
You can blindly call Directory.CreateDirectory without the Directory.Exists check first - it won't throw if the directory is already there.Weiser
@Tim: Wasn't sure so I threw it in there anywho. Thanks for the info though.Belen
And don't forget about Path.GetDirectoryName(string path) to get the directory from your full pathWillowwillowy
@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.Belen
*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.Decamp
This doesn't work as it would create also a directory with the file name.Hereby
T
188

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.

Triglyph answered 17/8, 2013 at 17:12 Comment(1)
If you are dealing with long path (256+) see #5189027Triennial
B
140
DirectoryInfo di = Directory.CreateDirectory(path);
Console.WriteLine("The directory was created successfully at {0}.",
    Directory.GetCreationTime(path));

See this MSDN page.

Belen answered 8/7, 2010 at 7:56 Comment(6)
You can blindly call Directory.CreateDirectory without the Directory.Exists check first - it won't throw if the directory is already there.Weiser
@Tim: Wasn't sure so I threw it in there anywho. Thanks for the info though.Belen
And don't forget about Path.GetDirectoryName(string path) to get the directory from your full pathWillowwillowy
@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.Belen
*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.Decamp
This doesn't work as it would create also a directory with the file name.Hereby
T
17

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

Thoughtout answered 8/7, 2010 at 7:55 Comment(0)
C
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.

Cohdwell answered 8/7, 2010 at 7:56 Comment(2)
path without file name :)Garland
"all directories and subdirectiories" Incorrect: it will create, at most, one directory and all the required subdirectories.Hake
S
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.

Snippy answered 8/7, 2010 at 7:54 Comment(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).Plumbiferous
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.Plumbiferous
@Plumbiferous - answer updated... hope it meets your standards now ;)Snippy
:) it does :) (it was not my point to prove you wrong or to offend you, but beginners can use any clarification in the answers)Plumbiferous
A
2

You should use Directory.CreateDirectory.

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

Adali answered 8/7, 2010 at 7:56 Comment(1)
Remarks: Any and all directories specified in path are created ... ahh kewl! cheers :)Reed
V
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?

Violette answered 8/7, 2010 at 9:41 Comment(1)
@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 :)Violette
M
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);
        }
    }

}

}

Melitamelitopol answered 8/7, 2010 at 8:0 Comment(3)
I should downgrade this because of this line: using Microsoft.VisualBasic; Evil!!Reed
And why is Microsoft.VisualBasic evil?? It's an assembly like anyone else in the .Net Framework.Willowwillowy
I suppose because your importing the namespace of a whole other language unnecessarily..?Melitamelitopol
H
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"));
        }
    }
}
Hamm answered 2/12, 2016 at 6:22 Comment(3)
It seems like the questioner wanted to create files rather than copy them.Houck
@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?Hamm
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.Houck

© 2022 - 2024 — McMap. All rights reserved.