c++17 filesystem::remove_all 带通配符路径
c++17 filesystem::remove_all with wildcard path
我想删除所有文件、文件夹和子文件夹,但不删除父文件夹。
所以我尝试使用 filesystem::remove_all 和通配符,但这似乎不起作用。
filesystem::removeall("pathtofolder/*");
没有例外,但它没有删除任何东西。
是否不允许使用通配符?
我真的需要为 pathtofolder
中的每个文件和文件夹调用 removeall
方法吗?
Are wildcards are not allowed?
不支持globbing (wildcards) in std::filesystem::remove_all
:
Deletes the contents of p
(if it is a directory) and the contents of all its subdirectories, recursively, then deletes p
itself as if by repeatedly applying the POSIX remove
. Symlinks are not followed (symlink is removed, not its target)
Do I really need to call for each file and folder inside of pathtofolder the removeall method?
是的,因此您的电话应该是这样的:
#include <cstdint>
#include <exception>
#include <filesystem>
#include <iostream>
#include <system_error>
int main() {
try {
std::uintmax_t count = 0;
// loop over all the "directory_entry"'s in "pathtofolder":
for(auto& de : std::filesystem::directory_iterator("pathtofolder")) {
// returns the number of deleted entities since c++17:
count += std::filesystem::remove_all(de.path());
}
std::cout << "deleted " << count << " files and directories\n";
} catch(const std::exception& ex) {
// The overloads that does not take a std::error_code& parameter throws
// filesystem_error on underlying OS API errors, constructed with p as
// the first path argument and the OS error code as the error code
// argument.
// directory_iterator: throws if the directory doesn't exist
// remove_all: does NOT throw if the path doesn't exist
std::cerr << ex.what() << std::endl;
}
}
请注意,如果 de.path()
不存在,则 不是 一个 OS API 错误,它不会 throw
一个例外。它将 return 0
删除文件和目录(或 false
在 C++17 之前)。
但是,如果 pathtofolder
不存在,directory_iterator()
将抛出 filesystem_error
。
我认为不允许使用通配符,
从 documentation 看来 std::filesystem::remove/remove_all 映射到 POSIX 系统上的 unlink/rmdir 和 DeleteFileW/RemoveDirectoryW 上的 Windows.
两者都不接受通配符。
见:
How to remove multiple files in C using wildcards?
@TedLyngmo 提供了一个有效的解决方案;我通常将这些东西添加到实用程序头文件中,例如在我的 src/util/filesystem.hpp
中,我输入:
namespace util {
namespace filesystem {
std::uintmax_t remove_all_inside(const std::filesystem::path& dir) {
std::uintmax_t removed_items_count { 0 };
if (not is_directory(dir)) {
throw std::invalid_argument("Not a directory: " + dir.str());
}
for(auto& dir_element : std::filesystem::directory_iterator(dir)) {
removed_items_count += std::filesystem::remove_all(dir_element .path());
}
return removed_items_count;
}
} // namespace filesystem
} // namespace util
然后我可以写:
#include <util/filesystem.hpp>
// ... etc etc ...
util::filesystem::remove_all_inside("/path/to/folder");
这种方法的一个很好的方面是它可以与标准的早期版本一起工作——您只需使用一些预处理器魔法来根据 C++ 版本选择 std::filesystem
或 boost::filesystem
;但是使用效用函数的代码保持不变。
示例:
std::wregex regExpName { LR"(^.*\.tmp$)" };
const auto tmpPath { std::filesystem::temp_directory_path() };
for (const auto& element : std::filesystem::directory_iterator(tmpPath))
if (not element.is_directory() and std::regex_match(element.path().filename().wstring(), regExpName))
std::filesystem::remove(element.path());
我想删除所有文件、文件夹和子文件夹,但不删除父文件夹。
所以我尝试使用 filesystem::remove_all 和通配符,但这似乎不起作用。
filesystem::removeall("pathtofolder/*");
没有例外,但它没有删除任何东西。
是否不允许使用通配符?
我真的需要为 pathtofolder
中的每个文件和文件夹调用 removeall
方法吗?
Are wildcards are not allowed?
不支持globbing (wildcards) in std::filesystem::remove_all
:
Deletes the contents of
p
(if it is a directory) and the contents of all its subdirectories, recursively, then deletesp
itself as if by repeatedly applying the POSIXremove
. Symlinks are not followed (symlink is removed, not its target)
Do I really need to call for each file and folder inside of pathtofolder the removeall method?
是的,因此您的电话应该是这样的:
#include <cstdint>
#include <exception>
#include <filesystem>
#include <iostream>
#include <system_error>
int main() {
try {
std::uintmax_t count = 0;
// loop over all the "directory_entry"'s in "pathtofolder":
for(auto& de : std::filesystem::directory_iterator("pathtofolder")) {
// returns the number of deleted entities since c++17:
count += std::filesystem::remove_all(de.path());
}
std::cout << "deleted " << count << " files and directories\n";
} catch(const std::exception& ex) {
// The overloads that does not take a std::error_code& parameter throws
// filesystem_error on underlying OS API errors, constructed with p as
// the first path argument and the OS error code as the error code
// argument.
// directory_iterator: throws if the directory doesn't exist
// remove_all: does NOT throw if the path doesn't exist
std::cerr << ex.what() << std::endl;
}
}
请注意,如果 de.path()
不存在,则 不是 一个 OS API 错误,它不会 throw
一个例外。它将 return 0
删除文件和目录(或 false
在 C++17 之前)。
但是,如果 pathtofolder
不存在,directory_iterator()
将抛出 filesystem_error
。
我认为不允许使用通配符,
从 documentation 看来 std::filesystem::remove/remove_all 映射到 POSIX 系统上的 unlink/rmdir 和 DeleteFileW/RemoveDirectoryW 上的 Windows.
两者都不接受通配符。
见: How to remove multiple files in C using wildcards?
@TedLyngmo 提供了一个有效的解决方案;我通常将这些东西添加到实用程序头文件中,例如在我的 src/util/filesystem.hpp
中,我输入:
namespace util {
namespace filesystem {
std::uintmax_t remove_all_inside(const std::filesystem::path& dir) {
std::uintmax_t removed_items_count { 0 };
if (not is_directory(dir)) {
throw std::invalid_argument("Not a directory: " + dir.str());
}
for(auto& dir_element : std::filesystem::directory_iterator(dir)) {
removed_items_count += std::filesystem::remove_all(dir_element .path());
}
return removed_items_count;
}
} // namespace filesystem
} // namespace util
然后我可以写:
#include <util/filesystem.hpp>
// ... etc etc ...
util::filesystem::remove_all_inside("/path/to/folder");
这种方法的一个很好的方面是它可以与标准的早期版本一起工作——您只需使用一些预处理器魔法来根据 C++ 版本选择 std::filesystem
或 boost::filesystem
;但是使用效用函数的代码保持不变。
示例:
std::wregex regExpName { LR"(^.*\.tmp$)" };
const auto tmpPath { std::filesystem::temp_directory_path() };
for (const auto& element : std::filesystem::directory_iterator(tmpPath))
if (not element.is_directory() and std::regex_match(element.path().filename().wstring(), regExpName))
std::filesystem::remove(element.path());