C++ – 在Windows/Linux上创建单级目录以及多级目录的跨平台方法
1 C++创建目录
本文将对使用C++在Windows和Linux系统上创建单级目录与多级目录的普通方法进行总结,本文将不会使用C++14新增的std::filesystem的标准库方法。
1.1 在Windows/Linux上创建单级目录
1.1.1 在Windows上创建单级目录
在Windows上创建单级目录使用direct.h下的_mkdir
方法,关于direct.h可参考维基百科,
使用方法如下:
#include <io.h>
#include <direct.h>
int main()
{
std::string folderPath = "E:\\database\\test\\test2\\test3";
if (0 != _access(folderPath.c_str(), 0))
{
int ret = _mkdir(folderPath.c_str());
if (ret == -1)
return ret;
}
return 0;
}
1.1.2 在Linux上创建单级目录
在Linux系统上创建单级目录使用mkdir
方法。
关于mkdir
方法,
函数原型
int mkdir(const char *pathname, mode_t mode);
函数说明
mkdir()函数以mode方式创建一个以参数pathname命名的目录,mode定义新创建目录的权限。
函数返回值
若目录创建成功,则返回0;否则返回-1,并将错误记录到全局变量errno中。
而参数mode可设置为以下值:
- S_IRWXU 00700权限,代表该文件所有者拥有读,写和执行操作的权限
- S_IRUSR(S_IREAD) 00400权限,代表该文件所有者拥有可读的权限
- S_IWUSR(S_IWRITE) 00200权限,代表该文件所有者拥有可写的权限
- S_IXUSR(S_IEXEC) 00100权限,代表该文件所有者拥有执行的权限
- S_IRWXG 00070权限,代表该文件用户组拥有读,写和执行操作的权限
- S_IRGRP 00040权限,代表该文件用户组拥有可读的权限
- S_IWGRP 00020权限,代表该文件用户组拥有可写的权限
- S_IXGRP 00010权限,代表该文件用户组拥有执行的权限
- S_IRWXO 00007权限,代表其他用户拥有读,写和执行操作的权限
- S_IROTH 00004权限,代表其他用户拥有可读的权限
- S_IWOTH 00002权限,代表其他用户拥有可写的权限
- S_IXOTH 00001权限,代表其他用户拥有执行的权限
使用mkdir
函数创建单级目录的示例代码如下,
#include <sys/stat.h>
#include <sys/types.h>
#include "stdio.h"
#include "unistd.h"
int main()
{
std::string folderPath = "E:\\database\\test\\test2\\test3";
if (access(folderPath.c_str(), F_OK) != 0)
{
int ret = mkdir(folderPath, 0755);
if (ret == -1)
return ret;
}
return 0;
}
1.2 在Windows/Linux上创建多级目录
上述1.1节中主要介绍的是创建单级目录的方式,创建单级目录成功的前提在于其父目录已经存在,如果父目录没有存在,则使用上述方式创建目录则会失败。例如,假如需要创建目录E:\\database\\test\\test2\\test3
,但是他的父目录E:\\database\\test\\test2\\
不存在,那么就会创建失败。所以我们需要对1.1节中的创建目录的方式进行修改和扩展,我们逐一检查指定的文件夹路径,如果某一级的文件夹路径不存在则创建该级目录,直到指定多级目录全部创建完成。
我们使用系统平台宏对上述1.1节中的方法进行了封装,使其成为一个跨Windows和Linux的创建多级目录的工具函数mkdir_in_os
,该函数如下:
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
#include <io.h>
#include <direct.h>
#elif defined(linux) || defined(__linux)
#include <sys/stat.h>
#include <sys/types.h>
#include "stdio.h"
#include "unistd.h"
#endif //
#include <iostream>
int mkdir_in_os(const std::string& dirPath)
{
std::string dirPathCopy = dirPath;
// 如果文件夹路径中有\\则全部替换为/
std::string oldstr = "\\";
std::string newstr = "/";
for (std::string::size_type pos = 0; pos != std::string::npos; pos += newstr.length())
{
pos = dirPathCopy.find(oldstr, pos);
if (pos != std::string::npos)
{
dirPathCopy.replace(pos, oldstr.length(), newstr);
}
else
{
break;
}
}
// 创建多级目录,如果父目录不存在则创建父目录,直到指定路径的文件夹创建完成
std::string::size_type pos = 0;
while (pos != std::string::npos)
{
std::string::size_type findpos = dirPathCopy.find(newstr, pos+1);
std::string substr = dirPathCopy.substr(0, findpos);
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
if (0 != _access(substr.c_str(), 0))
{
int ret = _mkdir(substr.c_str());
if (ret == -1)
return ret;
}
#elif defined(linux) || defined(__linux)
if (access(substr.c_str(), F_OK) != 0)
{
int ret = mkdir(substr, 0755);
if (ret == -1)
return ret;
}
#endif //
std::cout << substr << std::endl;
pos = findpos;
}
return 0;
}
使用示例如下:
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
#include <io.h>
#include <direct.h>
#elif defined(linux) || defined(__linux)
#include <sys/stat.h>
#include <sys/types.h>
#include "stdio.h"
#include "unistd.h"
#endif //
#include <iostream>
int mkdir_in_os(const std::string& dirPath)
{
std::string dirPathCopy = dirPath;
// 如果文件夹路径中有\\则全部替换为/
std::string oldstr = "\\";
std::string newstr = "/";
for (std::string::size_type pos = 0; pos != std::string::npos; pos += newstr.length())
{
pos = dirPathCopy.find(oldstr, pos);
if (pos != std::string::npos)
{
dirPathCopy.replace(pos, oldstr.length(), newstr);
}
else
{
break;
}
}
// 创建多级目录,如果父目录不存在则创建父目录,直到指定路径的文件夹创建完成
std::string::size_type pos = 0;
while (pos != std::string::npos)
{
std::string::size_type findpos = dirPathCopy.find(newstr, pos+1);
std::string substr = dirPathCopy.substr(0, findpos);
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
if (0 != _access(substr.c_str(), 0))
{
int ret = _mkdir(substr.c_str());
if (ret == -1)
return ret;
}
#elif defined(linux) || defined(__linux)
if (access(substr.c_str(), F_OK) != 0)
{
int ret = mkdir(substr, 0755);
if (ret == -1)
return ret;
}
#endif //
std::cout << substr << std::endl;
pos = findpos;
}
return 0;
}
int main()
{
std::string folderPath = "E:\\database\\test\\test2\\test3";
mkdir_in_os(folderPath.c_str());
return 0;
}
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – 在Windows/Linux上创建单级目录以及多级目录的跨平台方法
原文链接:https://www.stubbornhuang.com/2122/
发布于:2022年05月10日 11:23:34
修改于:2023年06月26日 20:12:17
当前分类随机文章推荐
- C++/OpenCV - 详解如何一步步将OpenCV的cv::Mat转换成深度学习模型推理所需的输入数据 阅读411次,点赞0次
- C++11 - std::function简要介绍以及可包装函数的几种形式总结 阅读3472次,点赞0次
- C++ - 将std::vector中的数值拷贝到数组中 阅读3635次,点赞1次
- C++11/std::thread - 线程管理join/detach 阅读2644次,点赞0次
- C++ - queue存储动态指针时正确释放内存 阅读6215次,点赞2次
- C++11 - 使用std::thread在类内部以成员函数作为多线程函数执行异步操作 阅读3204次,点赞0次
- C++ - 在Visual Studio中使用OpenMP加速for循环 阅读530次,点赞0次
- C++ - 左值和右值,右值引用与移动语义的概念与理解 阅读753次,点赞1次
- C++ - 最简单的将文本文件的内容一次性读取到std::string的方法 阅读5717次,点赞4次
- OpenCV | OpenGL - OpenCV的cv::mat转换为OpenGL的GL_TEXTURE_2D纹理数据 阅读538次,点赞0次
全站随机文章推荐
- C++11 - 快速学会正则表达式 阅读1652次,点赞2次
- Python – 解决opencv-python使用cv2.imwrite()保存中文路径图片失败的问题 阅读2316次,点赞0次
- 资源分享 - Handbook of Discrete and Computational Geometry, Second Edition 英文高清PDF下载 阅读2371次,点赞0次
- ThreeJS - 获取当前使用的three.js的版本 阅读821次,点赞0次
- 资源分享 - 3D Graphics for Game Programming 英文高清PDF下载 阅读1578次,点赞0次
- 资源分享 - Python深度学习:基于PyTorch (吴茂贵著) 高清PDF下载 阅读5197次,点赞0次
- 资源分享 - Python网络数据采集 (美 Ryan Mitchell著 陶俊杰 陈小莉译) 高清PDF下载 阅读3214次,点赞0次
- Windows Terminal、Power Shell设置conda环境,修复不显示conda虚拟环境名称的问题 阅读545次,点赞0次
- 资源分享 - Game AI Pro 360 - Guide to Tactics and Strategy 英文高清PDF下载 阅读2206次,点赞0次
- Mediapipe - 全身包含身体、手部、面部所有关键点标注位置对应图 阅读7130次,点赞4次
评论
169