c++创建目录的几种方式

system调用

这种方法简单粗野,适用于Linux系统。

代码如下:

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>

int main(int argc, char **argv)
{

	if (argc != 2)
	{
		cout << "Usage: " << argv[0] << " dir" << endl;
		return -1;
	}
	
	string path(argv[1]);
	string cmd("mkdir -p " + path);
	int ret = system(cmd.c_str());
	if (ret)
	{
		cout << "create dir error: " << ret << ", :" << strerror(errno) << endl;
		return -1;
	}
	cout << "system cmd create dir succ: " << argv[1] << endl;
	
	return 0;
}

直接使用系统命令执行Linux下mkdir命令创建目录,缺点是system系统调用时,要处理各种返回值情况。

mkdir函数

c++中提供了用于创建目录的函数,原型如下:

int mkdir(const char *path, mode_t mode);
// The file permission bits of the new directory shall be initialized from mode
// If path names a symbolic link, mkdir() shall fail and set errno to [EEXIST].
// Upon successful completion, mkdir() shall return 0. Otherwise, -1 shall be returned, no directory shall be created, and errno shall be set to indicate the error.

可能的错误如下:

  • [EACCES]
    • Search permission is denied on a component of the path prefix, or write permission is denied on the parent directory of the directory to be created.
  • [EEXIST]
    • The named file exists.
  • [ELOOP]
    • A loop exists in symbolic links encountered during resolution of the path argument.
  • [EMLINK]
    • The link count of the parent directory would exceed {LINK_MAX}.
  • [ENAMETOOLONG]
    • The length of the path argument exceeds {PATH_MAX} or a pathname component is longer than {NAME_MAX}.
  • [ENOENT]
    • A component of the path prefix specified by path does not name an existing directory or path is an empty string.
  • [ENOSPC]
    • The file system does not contain enough space to hold the contents of the new directory or to extend the parent directory of the new directory.
  • [ENOTDIR]
    • A component of the path prefix is not a directory.
  • [EROFS]
    • The parent directory resides on a read-only file system.

目录的权限如下:

  • User: S_IRUSR (read), S_IWUSR (write), S_IXUSR (execute)
  • Group: S_IRGRP (read), S_IWGRP (write), S_IXGRP (execute)
  • Others: S_IROTH (read), S_IWOTH (write), S_IXOTH (execute)

它们组合在一起,形成了如下快捷方式:

  • Read + Write + Execute: S_IRWXU (User), S_IRWXG (Group), S_IRWXO (Others)
  • DEFFILEMODE: Equivalent of 0666 = rw-rw-rw-
  • ACCESSPERMS: Equivalent of 0777 = rwxrwxrwx

使用mkdir函数,替换上面程序中的核心代码:

ret = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret && errno == EEXIST)
{
	cout << "dir: " << path << " aleardy exist" << endl;
}
else if (ret)
{
	cout << "create dir error: " << ret << ", :" << strerror(errno) << endl;
	return -1;
}
else
{
	cout << "mkdir create dir succ: " << path << endl;
}
boost::filesystem::create_directory

使用boost能够轻松实现跨平台的程序:

#include <boost/filesystem.hpp>

if (!boost::filesystem::is_directory(path))
{
 cout << "begin create path: " << path << endl;
 if (!boost::filesystem::create_directory(path))
 {
   cout << "create_directories failed: " << path << endl;
   return -1;
 }
}
else
{
 cout << path << " aleardy exist" << endl;
}

编译时增加-lboost_system -lboost_filesystem选项。

注意,以上函数只能用于创建单个目录,不能创建多级目录,否则会抛出异常:

begin create signal_dir: ./c/d
terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
  what():  boost::filesystem::create_directory: No such file or directory: "./c/d"
[1]    16669 abort (core dumped)  ./a.out ./c/d

如果需要一次创建多级目录,把create_directory替换为create_directories即可。

c++17中的std::filesystem::create_directory

原型如下:

bool create_directory( const std::filesystem::path& p ); # 以所有权限创建单个目录,父目录必须存在,如果目录已经存在,不会报错
bool create_directory( const std::filesystem::path& p, std::error_code& ec ) noexcept;

bool create_directory( const std::filesystem::path& p, const std::filesystem::path& existing_p ); # 与上面一样,只不过创建的目录的权限是从已经存在的目录属性拷贝过来的。这个特性依赖操作系统
bool create_directory( const std::filesystem::path& p, const std::filesystem::path& existing_p, std::error_code& ec ) noexcept;

bool create_directories( const std::filesystem::path& p ); # 创建层级目录,为每级不存在的目录调用第一个函数,如果目录已经存在,它什么也不做,且不会报错
bool create_directories( const std::filesystem::path& p, std::error_code& ec );
// 创建成功返回true,否则false

这个函数的使用与boost类似,示例代码如下:

#include <filesystem>
namespace fs = std::filesystem;

if (fs::create_directories(path))
{
	cout << "fs create dir succ: " << path << endl;
}
小节

如果已经安装了boost,建议直接使用boost库。

如果支持c++17,则使用标准库函数,新的编译器应该都支持了。

遗留代码,使用mkdir。

最后,直接使用system。

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值