【问题标题】:Are there any function in C or C++ or WinApi to create directory including all unexistent directories in specified path?C 或 C++ 或 WinApi 中是否有任何函数可以创建目录,包括指定路径中所有不存在的目录?
【发布时间】:2013-10-11 20:34:12
【问题描述】:

我需要一个 c# 的模拟

Directory.CreateDirectory("d:\\asd\\dsa\\123");

这将创建所有目录,即使磁盘 D 完全为空且没有任何目录。

我阅读了关于 WinApi CreateDirectory 的下一件事:
“ERROR_PATH_NOT_FOUND - 一个或多个中间目录不存在;此函数只会在路径中创建最终目录。”
所以这不是我要找的..

还有其他方法可以做我想做的事吗?

【问题讨论】:

    标签: c++ c winapi directory creation


    【解决方案1】:

    您是否尝试使用mkdir() 函数?另一种使用方式:

    1. boost filesystem:支持标准 MAX_PATH 大小 260。

      const char dir_path[] = "c:\\temp\\cplusplus";

      boost::filesystem::path dir(dir_path);
              if(boost::filesystem::create_directory(dir)) {
                  std::cout << "Success" << "\n";
              }
      
    2. SHCreateDirectoryEx function 适用于 Win XP(SP2) 和 更高。但是,它被限制为 247 个字符,小于其他 Win32 API 文件系统函数支持的标准 MAX_PATH (260)

    3. CreateDirectory function :248 个字符的路径的默认字符串大小限制。此限制与 CreateDirectory 函数如何解析路径有关。要将此限制扩展到32,767 宽字符,请调用函数的Unicode 版本并将"\\?\" 前缀添加到路径中。

    注意: 因为大多数 Boost.Filesystem 操作函数只是将类路径对象的内容传递给 Windows API,它们确实使用扩展长度前缀。但有些不起作用,因为 Windows 施加的限制。 -- Boost 警告。

    【讨论】:

    • SHCreateDirectoryEx 仅限于最大长度为 247 个字符的路径。 boost 文件系统限制为 260 个字符的路径,除非提供了扩展长度前缀 \\?\ (在上面的示例中为 "\\\\?\\c:\\temp\\cplusplus")。某些分解其参数的 boost 文件系统函数仍限制为 260 个字符。如果您需要长路径,则必须使用 CreateDirectory 自行滚动。
    • 奇怪的是 SHCreateDirectoryEx() 被限制为 247 个字符,比其他 Win32 API 文件系统函数支持的标准 MAX_PATH (260) 少。
    • 感谢您更新答案。 2 点值得注意:1: mkdir 从 Visual Studio 2005 开始已被弃用。可以使用符合 ISO C++ 的实现 _mkdir,但每次调用只能创建一个新目录。 2: 您描述 boost 文件系统的方式看起来没有长度限制。 This is not the case.
    • 再次感谢您更新答案。尽管您确实直接从 boost 文档中复制了注释,但这是完全错误的。限制因素是提升,而不是 Windows。 boost 页面上的部分继续解释出了什么问题,但没有强调它是 boost,而不是 Windows API 或文件系统。它甚至在这方面做出虚假声明。总的来说,我认为 boost 文件系统是一个特别低质量的提升贡献。
    【解决方案2】:

    检查您的特定编译器供应商是否为此提供了自己的 RTL 函数。例如,Delphi/C++Builder 有一个ForceDirectories() 函数可用。

    【讨论】:

      【解决方案3】:

      嗯,在 Perl/Ruby/Bash 中,你会,

          `/bin/mkdir -p $pathname` #perl
          %x(/bin/mkdir -p #{pathname}) #ruby
          /bin/mkdir -p $pathname #bash
      

      所以你可以唤起系统,

          system("mkdir -p pathname");
      

      添加:

      好吧,您想将给定的路径分成几部分并制作每个部分。在 C 中很容易做到(将 char* 和 char[] 更改为 std::string,将 strcat 更改为 += 对于 c++),

      int MakeDir( char* pathname )
      {
          struct stat sbuf;
          if( stat(pathname, &sbuf) < 0 )
          {
              mkdir(pathname,0); //set your permissions as you like in 2nd argument
              return(0);
          }
          else //exists? skip
          {
              //stat.st_mode tells file or dir
              if( S_ISDIR(stat.st_mode) ) { return(0); }
              else if( S_ISREG(stat.st_mode) ) { return(-1); }
              else if( S_ISFIFO(stat.st_mode) ) { return(-1); }
              else if( S_LNK(stat.st_mode) ) { return(0); } //can link to dir
              else { return(-1); }
          }
          return(0);
      };
      ////char PATHSEP = "\/"; //unix/linux //not needed, just use 'mkdir -p'
      char PATHSEP = "\\"; //windows
      int MkdirPath( char *pathname )
      {
          char parts = strdup(pathname);
          char buildpath[strlen(pathname)] = "";
          char* part = strtok(parts,PATHSEP);
          while ( part )
          {
              strcat(pathname, PATHSEP); strcat(pathname, part);
              if( MakeDir( pathname ) < 0 ) { break; }
              part = strtok(NULL,PATHSEP);
          }
          return(0);
      };
      

      【讨论】:

      • 安装 cygwin/mingw :-)
      • 我尽量避开窗户
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 2020-04-11
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多