编号的唯一文件
Numbered unique files
我想创建唯一的文件,必要时在文件名后面加一个数字(类似于浏览器通常命名下载文件的方式(。
以下是我尝试做的,但使用目录(使用<filesystem>
库(:
#include <filesystem>
namespace fs = std::filesystem;
template <typename... Args> std::string concatenate(Args&&... args) {
std::ostringstream sstr;
(sstr << ... << std::forward<Args>(args));
return sstr.str();
}
fs::path unique_dir(const fs::path &base, unsigned max_tries) {
if(fs::create_directories(base))
return base;
for(unsigned i = 1; i < max_tries; ++i) {
fs::path p = base;
p += concatenate('_', i);
if(fs::create_directory(p))
return p;
}
throw std::runtime_error("unique_dir: gave up");
}
int main() {
unique_dir("my_dir", 3); // creates my_dir
unique_dir("my_dir", 3); // creates my_dir_1
unique_dir("my_dir", 3); // creates my_dir_2
unique_dir("my_dir", 3); // throws
}
如何对文件执行同样的操作?
一些精度:
- 它不需要高性能(它适用于代码中非常冷的部分(
- 非跨平台是可以的,只要有Linux、Windows和Mac的变体
- 我不想使用
mkstemp
类型的函数,因为它需要在文件名中放入一个非用户友好的id
提前谢谢。
对于目录,您正在检查目录的创建是否有效。对于文件,您可以通过检查特定路径是否指向现有文件来实现此效果,如果不是,则创建它:
fs::path unique_file(const fs::path &base, unsigned max_tries) {
if(!fs::exists(base)) {
std::ofstream ofs(base);
return base;
}
for(unsigned i = 1; i < max_tries; ++i) {
fs::path p = base;
p += concat() << '_' << i;
if(!fs::exists(p)) {
std::ofstream ofs(p);
return p;
}
}
throw std::runtime_error("unique_file: gave up");
}
这里是一个POSIX系统的解决方案,使用open()
:
#include <fcntl.h> // open()
#include <unistd.h> // close()
fs::path unique_file(const fs::path &base, unsigned max_tries) {
fs::path p(base);
for(unsigned i = 1; i <= max_tries; ++i) {
// O_CREAT | O_EXCL will create the file if it does not exist, and fail otherwise
// 0666 : Read + Modify permissions for everybody
int fd = open(p.c_str(), O_CREAT | O_EXCL, 0666);
if(fd != -1) {
if(close(fd) == -1) // We immediately close the file, which might be a waste
throw fs::filesystem_error("unique_file: POSIX close() error", p, std::error_code(errno, std::generic_category()));
return p;
}
// EEXIST is set if open() failed because the file already existed
if(errno != EEXIST)
throw fs::filesystem_error("unique_file: POSIX open() error", p, std::error_code(errno, std::generic_category()));
errno = 0;
p = base.parent_path() / base.stem();
p += concatenate('_', i);
p += base.extension();
}
throw std::runtime_error("unique_file: gave up");
}
Windows似乎提供了_sopen_s
功能,该功能提供了相同的_O_CREAT | _O_EXCL
标志组合。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- c++多进程编写一个唯一的文件
- 我需要编写一个程序来读取一个文件,该文件将输出所有唯一的整数,如果已经看到整数,它将被关闭
- 尝试使用while循环从文件中读取数据.还必须检查以确保第一个和唯一的值不是-1
- 尝试创建一个读取.txt文件,显示它,计数唯一单词的程序,并在使用了多少次的情况下显示独特的单词.C
- 从输入文件读取整数,仅存储数组C 中的唯一整数
- 确定文本文件中的值是否唯一
- C++ 显示在 txt 文件中找到的唯一日期及其相关价格
- 使用外部定义的自定义删除程序在头文件中定义唯一指针
- 枚举用于多个文件,或多个文件的自动唯一常量
- 输入文件到数组,唯一的字
- 计算文件中唯一单词的最有效结构[c++]
- 如何在c++中管理文件唯一id
- C++ "for loop"将数据保存在数组中,然后写入文件唯一数据