【问题标题】:How do I create a file AND any folders, if the folders don't exist?如果文件夹不存在,如何创建文件和任何文件夹?
【发布时间】:2011-03-13 05:02:38
【问题描述】:

假设我希望创建(或覆盖)以下文件:- C:\Temp\Bar\Foo\Test.txt

使用File.Create(..)方法,可以做到。

但是,如果我没有以下任一文件夹(来自上面的示例路径)

  • 温度
  • 酒吧

然后我得到一个 DirectoryNotFoundException 抛出。

所以.. 给定一个路径,我们如何递归地创建所有必要的文件夹来创建该路径的文件..?如果存在 Temp 或 Bar 文件夹,但 Foo 不存在.. . 那么它也被创建了。

为简单起见,我们假设没有安全问题——所有权限都很好,等等。

【问题讨论】:

标签: c# .net file-access


【解决方案1】:

您需要检查路径的两个部分(目录和文件名),如果不存在则创建每个部分。

使用File.ExistsDirectory.Exists 找出它们是否存在。 Directory.CreateDirectory 将为您创建整个路径,因此如果目录不存在,您只需调用一次,然后只需创建文件。

【讨论】:

  • 对于 Directory.CreateDirectory,您不需要查看存在哪个部分。它将创建所需的所有目录(唯一要确保的是目标目录不存在)。
  • 我建议在这种情况下删除你回答的第一行,因为他不需要从根目录检查每个部分,只需检查完整路径并在它不存在时创建它。
  • @Gertjan - 答案已更新...希望它现在符合您的标准;)
  • :) 确实如此 :) (我的意思不是要证明你错了或冒犯你,但初学者可以在答案中使用任何澄清)
【解决方案2】:

在创建文件之前使用Directory.CreateDirectory。它会递归地为您创建文件夹。

【讨论】:

    【解决方案3】:

    您应该使用 Directory.CreateDirectory。

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

    【讨论】:

    • 备注:path 中指定的所有目录都已创建 ... ahh kewl!干杯:)
    【解决方案4】:

    。给定一个路径,我们如何递归地创建创建文件所需的所有文件夹.. 为该路径

    创建路径指定的所有目录和子目录。

    Directory.CreateDirectory(path);
    

    然后你可以创建一个文件。

    【讨论】:

    • 没有文件名的路径:)
    • "所有目录和子目录" 不正确:它最多会创建一个目录和所有需要的子目录。
    【解决方案5】:
    DirectoryInfo di = Directory.CreateDirectory(path);
    Console.WriteLine("The directory was created successfully at {0}.",
        Directory.GetCreationTime(path));
    

    this MSDN page

    希望能帮到你!

    【讨论】:

    • 你可以盲目地调用Directory.CreateDirectory而不先检查Directory.Exists - 如果目录已经存在,它不会抛出。
    • @Tim:不确定所以我把它扔在那里。不过感谢您提供的信息。
    • 别忘了Path.GetDirectoryName(string path) 从完整路径中获取目录
    • @Oliver:Directory 和 DirectoryInfo 类有一大堆功能,但我提供的代码足以让他朝着正确的方向前进。我认为链接也扩展了很多。
    • *注意:变量path 不应包含文件名。所以使用 OP 的例子path 应该是C:\Temp\Bar\Foo。调用Directory.CreateDirectory(path); 后,您仍然需要调用File.Create("C:\Temp\Bar\Foo\Test.txt"); 来创建文件。
    【解决方案6】:

    你想要 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);
            }
        }
    
    }
    

    }

    【讨论】:

    • 我应该降级因为这条线:using Microsoft.VisualBasic; Evil!!
    • 为什么 Microsoft.VisualBasic 是邪恶的?它是一个与 .Net Framework 中的其他任何人一样的程序集。
    • 我想是因为您不必要地导入了另一种语言的命名空间..?
    【解决方案7】:

    假设您的程序集/exe 本身具有FileIO 权限,那是不对的。您的应用程序可能无法以管理员权限运行。考虑Code Access Securityrequesting permissions 很重要 示例代码:

    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?

    【讨论】:

    • @Pure.Krome:虽然我的回答偏离了目标,但在访问特权资源时仍然要考虑安全性和访问控制。绝不要超越或使您的问题复杂化:)
    【解决方案8】:

    总结其他答案中的评论:

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

    Directory.CreateDirectory 将递归创建目录,如果目录已经存在,它将返回而不会出错。

    如果在C:\Temp\Bar\Foo 处恰好有一个文件Foo,则会抛出异常。

    【讨论】:

    【解决方案9】:

    以下代码将创建目录(如果不存在)然后复制文件

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

    【讨论】:

    • 提问者似乎想创建文件而不是复制它们。
    • @ThomasFritz 你是对的,但在我的回答中仍然有一些关于使用文件和文件夹的好信息,你不这么认为吗?我应该删除我的答案吗?
    • 我认为您不必删除您的答案本身:虽然它可能无法回答原始问题,但它被放置在一些可以做到这一点的答案之下。相反,您的答案是对不同主题的介绍,特别是文件的复制方式,我不介意 StackOverflow 答案之间的差异。如果您有时间,您可以做的就是调整答案的措辞,使其不会像所有答案中最完整的答案一样呈现出来,我认为这是夸大其词。
    猜你喜欢
    • 2018-09-05
    • 2016-06-26
    • 2011-06-21
    • 2014-11-24
    • 2011-01-19
    • 2018-02-10
    • 2013-09-18
    • 2011-02-19
    相关资源
    最近更新 更多