【问题标题】:If a folder does not exist, create it如果文件夹不存在,则创建它
【发布时间】:2020-07-12 05:00:58
【问题描述】:

我在我的应用程序中使用了FileUploader 控件。我想将文件保存到指定的文件夹。如果此文件夹不存在,我想先创建它,然后将我的文件保存到此文件夹中。如果该文件夹已存在,则只需将文件保存在其中即可。

我该怎么做?

【问题讨论】:

  • @JoeBlow - 哈 - 应该指定哪个答案不正确 - 现在页面更加混乱。 (他改变了接受的答案吗?还是没有?天哪!);-)
  • 我在寻找其他东西的同时来到这里,但令人惊讶的是,有多少人在用他们自己版本的同一个故事相互矛盾。 Microsoft 编写了 .NET Framework 和 MSDN。其他实现者(例如 Mono)是否尊重正确的行为与 MSDN 中描述的行为的正确性无关。哦,Mono 也做了正确的事情,那么争论在哪里?

标签: c# asp.net directory


【解决方案1】:

按照How can I create a folder dynamically using the File upload server control?使用下面的代码:

string subPath ="ImagesPath"; // Your code goes here

bool exists = System.IO.Directory.Exists(Server.MapPath(subPath));

if(!exists)
    System.IO.Directory.CreateDirectory(Server.MapPath(subPath));

【讨论】:

  • 为什么不:if (!Directory.Exists(path_to_check)) Directory.CreateDirectory(path_to_check);
  • 不需要检查文件夹是否存在。仔细阅读手册。
  • 检查和创建不是原子的。上面的代码有异味,存在竞争条件。您最好无条件地创建目录,并捕获 FileExists(或任何 C# 等效项)异常,以防函数被设计为抛出异常。
  • 就像其他人指出的那样,不需要调用Exists,它实际上会创建一个新的失败条件。
  • @MartinSmith:然后创建目录。之前不要检查是否存在。这不仅更短。它也不会给人以System.IO.Directory.CreateDirectory 的API 是什么的错误印象。 (而且它更快,但可能没关系)
【解决方案2】:

Directory.CreateDirectory 解释了如何尝试并在 FilePath 不存在时创建它。

Directory.Exists 解释了如何检查 FilePath 是否存在。但是,您不需要它,因为 CreateDirectory 会为您检查它。

【讨论】:

  • @Tavousi jeroenh 提供的这个功能将是一个好的开始;)
  • 目前似乎没有任何 msdn 文档链接可用,即使通过 msdn 搜索...
  • 链接现在很好
  • 这会启用竞争条件,请参阅accepted answer
【解决方案3】:

您可以使用 try/catch 子句并检查它是否存在:

  try
  {
    if (!Directory.Exists(path))
    {
       // Try to create the directory.
       DirectoryInfo di = Directory.CreateDirectory(path);
    }
  }
  catch (IOException ioex)
  {
     Console.WriteLine(ioex.Message);
  }

【讨论】:

  • 这是一个很好的答案,但是,根据 MSDN 文档,“创建路径中指定的任何和所有目录,除非它们已经存在或路径的某些部分无效。路径参数指定目录路径,而不是文件路径。如果目录已经存在,则此方法不执行任何操作。所以,你真的不需要调用 Directory.Exists(path)。
  • 这是真的,但这也是一个假设,所以无论 MSDN 说什么,最好检查而不是假设..
  • @DJ KRAZE,我相信 MSDN,除非它被证明是错误的。您建议相反 - 忽略 MSDN 所说的并在您的代码中添加额外(不必要的)检查。你在哪里画线?
  • ShellShock 我无处说忽略.. 这是一个自以为是的说法,我说最好不要假设而不是假设.. 再次阅读我所说的.. 谢谢
  • @DJKRAZE 没有人假设任何事情。手册里用简单的英文写的,不需要检查。
【解决方案4】:

如果路径不存在,您可以使用如下方法创建路径:

using System.IO;

private void CreateIfMissing(string path)
{
  bool folderExists = Directory.Exists(Server.MapPath(path));
  if (!folderExists)
    Directory.CreateDirectory(Server.MapPath(path));
}

【讨论】:

  • 不需要检查if (!folderExists)
  • @bazzilic 是的,但它揭示了意图。我不必猜测(或肯定知道)API 如何处理这个问题。任何读过这段代码的人都知道会发生什么。
  • 在多线程环境中(例如文件系统的状态),您只能选择锁定或 try-and-catch。上面的 sn-p 有一个竞争条件。该函数可能会抛出 FileExists 异常(或在 C# 中调用的任何内容)
  • “它揭示了意图”——这不是一个好的理由。你可以在代码中写一个注释。
【解决方案5】:
using System.IO

if (!Directory.Exists(yourDirectory))
    Directory.CreateDirectory(yourDirectory);

【讨论】:

    【解决方案6】:

    正如其他人所说,使用System.IO.Directory.CreateDirectory

    但是,您不需要先检查它是否存在。来自the documentation

    创建路径中指定的所有目录,除非它们已经存在或路径的某些部分无效。如果目录已经存在,则此方法不会创建新目录,而是返回现有目录的 DirectoryInfo 对象。

    【讨论】:

    • 然而微软代码示例通过首先检查目录是否存在而自相矛盾...
    • @Muflix 像这样 - 在目录上创建一个文件,例如“FILENAME”,但不要给它任何扩展名。然后尝试调用 Directory.Exists("FILENAME") 将返回 false,因为没有这样的目录。现在,如果您调用 CreateDirectory("FILENAME") 它将失败,因为那里已经存在具有该名称的“某物”。希望这是有道理的。
    • 错了!我您必须检查该文件夹是否存在。我刚刚发现这种方法有一个严重的问题。如果您不检查文件夹是否存在,除非您专门释放它,否则文件夹句柄将泄漏。我们在处理数百万个文件夹的应用程序中使用了这个示例。每次调用此方法时,应用程序都会保留目录的文件句柄。几个小时后,企业网络 NAS 在文件夹中打开了数百万个文件句柄。更新以包括检查免费的句柄
    • @soddoffBaldrick 你一定在代码中做错了什么,因为DirectoryDirectoryInfo 都没有对句柄做任何事情。最终,Directory.Create 归结为对 Win32 CreateDirectory 函数的一连串调用,并且该函数再次对句柄不做任何事情。您的句柄泄漏在其他地方。
    【解决方案7】:

    只写这一行:

    System.IO.Directory.CreateDirectory("my folder");
    
    • 如果文件夹尚不存在,则会创建
    • 如果文件夹已经存在,则该行将被忽略

    参考:Article about Directory.CreateDirectory at MSDN

    当然,你也可以在源文件的顶部写using System.IO;,然后每次要创建文件夹时写Directory.CreateDirectory("my folder");

    【讨论】:

    • 每个人都在谈论相同的答案,但我喜欢这里解释的简单性。非常容易和快速理解。 +1 来自我
    【解决方案8】:
    string root = @"C:\Temp";
    
    string subdir = @"C:\Temp\Mahesh";
    
    // If directory does not exist, create it.
    
    if (!Directory.Exists(root))
    {
    
    Directory.CreateDirectory(root);
    
    }
    

    CreateDirectory 也用于创建子目录。您所要做的就是指定将在其中创建此子目录的目录的路径。以下代码 sn -p 在C:\Temp directory 中创建一个 Mahesh 子目录。

    // Create sub directory
    
    if (!Directory.Exists(subdir))
    {
    
    Directory.CreateDirectory(subdir);
    
    }
    

    【讨论】:

      【解决方案9】:

      如果文件夹不存在,此方法将创建该文件夹,如果存在则不执行任何操作:

      Directory.CreateDirectory(path);
      

      【讨论】:

      • 这与 2012 年的答案有何不同?
      【解决方案10】:

      使用下面的代码。我使用此代码进行文件复制和创建新文件夹。

      string fileToCopy = "filelocation\\file_name.txt";
      String server = Environment.UserName;
      string newLocation = "C:\\Users\\" + server + "\\Pictures\\Tenders\\file_name.txt";
      string folderLocation = "C:\\Users\\" + server + "\\Pictures\\Tenders\\";
      bool exists = System.IO.Directory.Exists(folderLocation);
      
      if (!exists)
      {
         System.IO.Directory.CreateDirectory(folderLocation);
         if (System.IO.File.Exists(fileToCopy))
         {
           MessageBox.Show("file copied");
           System.IO.File.Copy(fileToCopy, newLocation, true);
         }
         else
         {
            MessageBox.Show("no such files");
         }
      }
      

      【讨论】:

      • 解释一下。它似乎做了更多检查(?)。
      【解决方案11】:

      从多个答案派生/组合,对我来说实现它就像这样简单:

      public void Init()
      {
          String platypusDir = @"C:\platypus";
          CreateDirectoryIfDoesNotExist(platypusDir);
      }
      
      private void CreateDirectoryIfDoesNotExist(string dirName)
      {
          System.IO.Directory.CreateDirectory(dirName);
      }
      

      【讨论】:

      • 将一个方法封装到本质上是一个精确的副本中的意义何在,只是名称略有不同?你真的没有从中获得任何好处。
      【解决方案12】:
      if (!Directory.Exists(Path.GetDirectoryName(fileName)))
      {
          Directory.CreateDirectory(Path.GetDirectoryName(fileName));
      }
      

      【讨论】:

      • CreateDirectory 已经处理了目录是否存在的检查。
      【解决方案13】:

      以下代码是我使用的最好的代码行,如果不存在,它将创建目录。

      System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/temp/"));
      

      如果目录已经存在,此方法不会创建新目录,而是返回现有目录的 DirectoryInfo 对象。 >

      【讨论】:

      • CreateDirectory 已经处理了目录是否存在的检查。
      • @bergmeister,谢谢。我刚刚越过了检查。它真的删除了条件检查。更新了!!
      【解决方案14】:

      创建一个新文件夹,给定父文件夹的路径:

              string pathToNewFolder = System.IO.Path.Combine(parentFolderPath, "NewSubFolder");
              DirectoryInfo directory = Directory.CreateDirectory(pathToNewFolder); 
             // Will create if does not already exist (otherwise will ignore)
      
      • 给定新文件夹的路径
      • 目录信息变量,以便您可以继续随意操作。

      【讨论】:

        【解决方案15】:

        如果文件夹不在图片文件夹或其他文件夹下,请使用此代码

        string subPath = HttpContext.Current.Server.MapPath(@"~/Images/RequisitionBarCode/");
        
        bool exists = System.IO.Directory.Exists(subPath);
        if(!exists)
            System.IO.Directory.CreateDirectory(subPath);
        
        string path = HttpContext.Current.Server.MapPath(@"~/Images/RequisitionBarCode/" + OrderId + ".png");
        

        【讨论】:

          【解决方案16】:

          一种奇特的方法是使用您想要的方法扩展FileUpload

          添加这个:

          public static class FileUploadExtension
          {
              public static void SaveAs(this FileUpload, string destination, bool autoCreateDirectory) { 
          
                  if (autoCreateDirectory)
                  {
                      var destinationDirectory = new DirectoryInfo(Path.GetDirectoryName(destination));
          
                      if (!destinationDirectory.Exists)
                          destinationDirectory.Create();
                  }
          
                  file.SaveAs(destination);
              }
          }
          

          然后使用它:

          FileUpload file;
          ...
          file.SaveAs(path,true);
          

          【讨论】:

          • 但是 FileUploadExtension 类在任何地方都没有使用(?)。
          • “扩展文件上传”是什么意思
          • @PeterMortensen docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…。在我的解决方案中,SaveAs 方法有另一个版本,带有第二个参数,告诉创建或不创建目录。包含新方法的类的名称必须与我正在扩展的类不同。这可能会引起混乱,但事实就是如此。
          猜你喜欢
          • 2022-01-11
          • 1970-01-01
          • 2014-07-20
          • 1970-01-01
          • 2017-06-28
          • 2013-11-05
          • 2011-01-19
          • 2018-02-10
          相关资源
          最近更新 更多