C++ – 在Windows/Linux上创建单级目录以及多级目录的跨平台方法
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – 在Windows/Linux上创建单级目录以及多级目录的跨平台方法
原文链接:https://www.stubbornhuang.com/2122/
发布于:2022年05月10日 11:23:34
修改于:2022年05月10日 11:24:34

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;
}
当前分类随机文章推荐
- C++ - const修饰符与指针 阅读200次,点赞1次
- C++11 - 构建一个符合实际应用要求的线程池 阅读975次,点赞0次
- C++ - RAII机制 阅读142次,点赞0次
- C++ - 导出接口函数和导出C++类 阅读19次,点赞0次
- C++11/std::thread - 线程的基本用法 阅读3083次,点赞0次
- C++ - Jni中的GetByteArrayElements和GetByteArrayRegion的区别和使用示例 阅读2262次,点赞0次
- C++STL容器 - std::map删除指定元素 阅读1284次,点赞0次
- C++11 - std::shared_ptr初始化的几种方式 阅读6641次,点赞2次
- C++STL容器 - std::vector元素访问方式总结 阅读629次,点赞0次
- C++11 - override关键字简要介绍 阅读1920次,点赞0次
全站随机文章推荐
- 深度学习 - 语音识别框架wenet中的CTC Prefix Beam Search算法的实现 阅读72次,点赞0次
- 资源分享 - Geometric Algebra for Computer Science - An Object-Oriented Approach to Geometry (First Edition) 英文高清PDF下载 阅读1923次,点赞0次
- 深度学习 - 理解LSTM网络[翻译] 阅读211次,点赞0次
- Modern OpenGL从零开始 - 在Visual Studio中配置OpenGL开发环境 阅读2287次,点赞0次
- 一文带你从欧拉角的角度搞懂左手坐标系到右手坐标系的转换 阅读13205次,点赞18次
- OpenCV - Mat与lplImage和CvMat的相互转换 阅读3494次,点赞0次
- C++11/std::atomic - 原子变量(不加锁实现线程互斥) 阅读5851次,点赞2次
- C++11 - 使用std::thread::join()/std::thread::detach()方法需要注意的点 阅读2466次,点赞0次
- Pytorch - 模型保存与加载以及如何在已保存的模型的基础上继续训练模型 阅读341次,点赞0次
- 资源分享 - Game AI Pro 360 - Guide to Tactics and Strategy 英文高清PDF下载 阅读1569次,点赞0次
评论
164