递归新建文件夹

本文介绍了一个使用Python编写的函数,该函数用于检查指定路径是否存在,如果不存在则创建该路径。通过os模块实现目录的创建,适用于自动化脚本中需要确保文件夹结构存在的场景。
import os

def mkdir(path):
    is_exits = os.path.exists(path)
    if not is_exits:
        os.makedirs(path)

if __name__ == '__main__':
    path = "./result/images"
    mkdir(path)
// // FilePath.h // /** \file FilePath.h */ #pragma once #include "vtString.h" #include <fstream> #include <io.h> /** * A portable class for reading directory contents. * * Example of use: \code for (dir_iter it("C:/temp"); it != dir_iter(); ++it) { if (it.is_hidden()) continue; if (it.is_directory()) printf("Directory: '%s'\n", it.filename().c_str()); else printf("File: '%s'\n", it.filename().c_str()); } \endcode */ class dir_iter { public: dir_iter(); dir_iter(const char*dirname); dir_iter(const wchar_t*dirname); ~dir_iter(); /// Returns true if the current object is a directory. bool is_directory(); /// Returns true if the current object is hidden. bool is_hidden(); /// Get the filename fo the current object. std::string filename(); std::wstring wfilename(); // Iterate the object to the next file/directory. void operator++(); // Test for inequality useful to test when iteration is finished. bool operator!=(const dir_iter &it;); long m_handle; private: struct _wfinddata_t m_data; }; //MBCS string 或者 Wide string vtString vtFindFileOnPaths(const vtStringArray &paths;, const char *filename); vtString2 vtFindFileOnPaths(const vtStringArray2 &paths;, const wchar_t *filename); bool vtCreateDir(const char *dirname); bool vtCreateDir(const wchar_t *dirname); void vtDestroyDir(const char *dirname); void vtDestroyDir(const wchar_t *dirname); int vtDeleteFile(const char *filename); int vtDeleteFile(const wchar_t *filename); const char *vtStartOfFileName(const char *szFullPath); const wchar_t *vtStartOfFileName(const wchar_t *szFullPath); vtString vtExtractPath(const char *szFullPath, bool bTrailingSlash); vtString2 vtExtractPath(const wchar_t *szFullPath, bool bTrailingSlash); bool vtPathIsAbsolute(const char *szPath); bool vtPathIsAbsolute(const wchar_t *szPath); vtString vtPathLevelUp(const char *src); vtString2 vtPathLevelUp(const wchar_t *src); vtString get_line_from_stream(std::ifstream &input;); vtString2 get_line_from_stream(std::wifstream &input;); //bFull为ture包括所有扩展名;否则最后一个扩展名 void vtRemoveFileExtensions(vtString& fname,bool bFull = false); void vtRemoveFileExtensions(vtString2& fname,bool bFull = false); //bFull为ture包括所有扩展名;否则最后一个扩展名 vtString vtGetExtensions(const vtString &fname;, bool bFull = false); vtString2 vtGetExtensions(const vtString2 &fname;, bool bFull = false); bool vtChangeFileExtension(vtString& input, const char *extension); bool vtChangeFileExtension(vtString2& input, const wchar_t *extension); bool vtFileExists(const char *fname); bool vtFileExists(const wchar_t *fname); #pragma comment(lib, "shell32.lib") bool vtCopyFile( const char* from,const char * to, bool bFailIfExists=true); bool vtCopyFile( const wchar_t* from,const wchar_t * to, bool bFailIfExists=true); bool vtCopyTree(const char* from,const char * to); bool vtCopyTree(const wchar_t* from,const wchar_t * to); bool vtFolderExists(const char *fname); bool vtFolderExists(const wchar_t *fname); bool vtFilePathExists(const char *fname); bool vtFilePathExists(const wchar_t *fname); int vtGetFileSize(const char *fname); int vtGetFileSize(const wchar_t *fname); void vtSetEnvironmentVar(const char* var, const char*value); void vtSetEnvironmentVar(const wchar_t* var, const wchar_t*value); #include "windows.h" bool vtGetModuleFullPath(const char* modulename,vtString& fullpath); bool vtGetModuleFullPath(const wchar_t* modulename,vtString2& fullpath); ///////////////////////////////////////////// // Open a file using a UTF-8 or wide character filename. FILE *vtFileOpen(const char *fname_mbcs, const char *mode); FILE *vtFileOpen(const wchar_t *fname_wide, const wchar_t *mode); vtString vtChooseFolder(HWND hWnd =NULL); vtString2 vtChooseFolder2(HWND hWnd=NULL);
在 C++ 中递归创建多级目录(即新建嵌套的文件夹,如 `a/b/c/d`),需要逐层判断每一级目录是否存在,如果不存在则创建。由于标准库直到 **C++17** 才引入了原生支持文件系统的 `<filesystem>` 模块,因此实现方式取决于你使用的 C++ 标准。 --- ## ✅ 方法一:使用 C++17 的 `<filesystem>`(推荐) 这是最简单、跨平台的方式(支持 Windows、Linux、macOS)。 ### 示例代码:递归创建目录 ```cpp #include <iostream> #include <filesystem> namespace fs = std::filesystem; bool createDirectories(const std::string& path) { try { // create_directories 会自动递归创建所有缺失的父目录 if (fs::create_directories(path)) { std::cout << "✅ 成功创建目录: " << path << std::endl; } else { std::cout << "ℹ️ 目录已存在: " << path << std::endl; } return true; } catch (const fs::filesystem_error& ex) { std::cerr << "❌ 创建目录失败: " << ex.what() << std::endl; return false; } } int main() { std::string dirPath = "a/b/c/d"; // 多级嵌套目录 if (createDirectories(dirPath)) { std::cout << "所有目录创建成功!" << std::endl; } else { std::cout << "创建失败。" << std::endl; } return 0; } ``` ### 🔧 编译命令(需启用 C++17) #### Linux / macOS(g++ 或 clang++): ```bash g++ -std=c++17 -o mkdir_recursive main.cpp ``` #### Windows(MinGW 或 MSVC): 确保使用支持 C++17 的编译器(如 Visual Studio 2017+ 或 MinGW-w64)。 > ⚠️ 注意:某些旧版本 MinGW 不完整支持 `<filesystem>`,可尝试链接 `-lstdc++fs`: ```bash g++ -std=c++17 -lstdc++fs -o mkdir_recursive main.cpp ``` --- ## ✅ 方法二:手动递归实现(兼容旧版 C++) 如果你不能使用 C++17,可以自己解析路径并逐层创建。 ### 示例代码(跨平台,适用于 C++98/11/14) ```cpp #include <iostream> #include <string> #include <vector> #include <sstream> #include <cstdlib> #ifdef _WIN32 #include <direct.h> #define MKDIR(path) _mkdir(path) #define ACCESS _access #else #include <sys/stat.h> #define MKDIR(path) mkdir(path, 0755) #define ACCESS access #endif // 分割字符串(按 '/' 或 '\') std::vector<std::string> splitPath(const std::string& path) { std::vector<std::string> parts; std::stringstream ss(path); std::string part; char delimiter = '/'; #ifdef _WIN32 delimiter = '\\'; #endif while (std::getline(ss, part, delimiter)) { if (!part.empty()) { parts.push_back(part); } } return parts; } bool createDirectoryIfNotExists(const std::string& dir) { if (ACCESS(dir.c_str(), 0) != 0) { int result = MKDIR(dir.c_str()); if (result != 0) { std::cerr << "❌ 无法创建目录: " << dir << std::endl; return false; } else { std::cout << "📁 创建目录: " << dir << std::endl; } } return true; } bool createDirectoriesRecursive(std::string fullPath) { std::vector<std::string> parts = splitPath(fullPath); std::string currentPath; #ifdef _WIN32 // 处理盘符,如 C: size_t pos = fullPath.find(':'); if (pos != std::string::npos && pos == 1) { currentPath = parts[0] + ":\\"; SetCurrentDirectoryA(currentPath.c_str()); // 切换驱动器 for (size_t i = 1; i < parts.size(); ++i) { if (i == 1) currentPath = parts[0] + ":" + "\\" + parts[1]; else currentPath += "\\" + parts[i]; if (!createDirectoryIfNotExists(currentPath)) return false; } return true; } else { currentPath = "."; } #else currentPath = "."; #endif for (const auto& part : parts) { #ifdef _WIN32 currentPath += "\\" + part; #else currentPath += "/" + part; #endif if (!createDirectoryIfNotExists(currentPath)) { return false; } } return true; } int main() { std::string path = "folder/subfolder/deep/nested/path"; if (createDirectoriesRecursive(path)) { std::cout << "✅ 所有目录创建成功!" << std::endl; } else { std::cout << "❌ 创建失败。" << std::endl; } return 0; } ``` ### 📌 特点: - 兼容 C++98 及以上。 - 支持 Windows 和 Unix-like 系统。 - 自动处理 `/` 和 `\` 路径分隔符。 - 使用 `access()` 检查目录是否存在。 --- ## ✅ 方法三:使用 Boost.Filesystem(第三方库) Boost 提供了强大的文件系统支持,适用于老版本 C++。 ```cpp #include <boost/filesystem.hpp> #include <iostream> int main() { boost::filesystem::path p("a/b/c/d"); try { if (boost::filesystem::create_directories(p)) { std::cout << "✅ 成功创建: " << p << std::endl; } else { std::cout << "ℹ️ 已存在: " << p << std::endl; } } catch (const boost::filesystem::filesystem_error& ex) { std::cerr << "❌ 错误: " << ex.what() << std::endl; } return 0; } ``` 编译: ```bash g++ -std=c++11 -o boost_mkdir main.cpp -lboost_filesystem -lboost_system ``` --- ## 🔍 小结对比 | 方法 | 是否需要 C++17 | 是否跨平台 | 是否依赖外部库 | 推荐程度 | |------|----------------|------------|----------------|----------| | `<filesystem>` | ✅ 是 | ✅ 是 | ❌ 否 | ⭐⭐⭐⭐⭐ | | 手动实现 | ❌ 否 | ✅ 是 | ❌ 否 | ⭐⭐⭐⭐☆ | | Boost.Filesystem | ❌ 否 | ✅ 是 | ✅ 是 | ⭐⭐⭐☆☆ | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值