From 87d851ed7f7a3493a71a615abb21834b3dae80b9 Mon Sep 17 00:00:00 2001 From: hfmlhk Date: Mon, 1 Apr 2024 11:04:07 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feature:=201.=E5=AE=9E=E7=8E=B0=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=95=B4=E4=B8=AA=E6=96=87=E4=BB=B6=E5=A4=B9=E5=8A=9F?= =?UTF-8?q?=E8=83=BD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/util/fs.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++--- modules/util/fs.h | 17 +++++------ 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/modules/util/fs.cpp b/modules/util/fs.cpp index e1f9979..9716935 100644 --- a/modules/util/fs.cpp +++ b/modules/util/fs.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -254,11 +255,72 @@ bool MakeDirectory(const std::string &origin_dir_path, bool allow_log_print) return true; } -bool RemoveDirectory(const std::string &dir) + +bool RemoveDirectory(const std::string &dir, bool is_reserve_dir, bool allow_log_print) { - LogUndo(); - (void)dir; - return false; + DIR *dp = opendir(dir.c_str()); + if (dp == nullptr) { + // 无法打开目录,直接结束 + if (errno == ENOENT && allow_log_print) { + LogWarn("directory %s does not exist", dir.c_str()); + } else { + if (allow_log_print) { + LogWarn("error opening directory %s, errno: %d", dir.c_str(), errno); + } + } + return false; + } + + struct dirent *entry; + while ((entry = readdir(dp)) != nullptr) { + std::string entry_name = entry->d_name; + if (entry_name == "." || entry_name == "..") { + // 目录系统的 . 和 .. 内容,直接略过 + continue; + } + + // 依次查看每一个文件或者目录的属性 + std::string full_path = dir + "/" + entry_name; + struct stat statbuf; + if (!stat(full_path.c_str(), &statbuf)) { + if (S_ISDIR(statbuf.st_mode)) { + // 属性为目录,递归删除目录的内容 + if (!RemoveDirectory(full_path, is_reserve_dir, allow_log_print)) { + closedir(dp); + return false; + } + } else { + // 属性为文件,直接删除文件 + if (remove(full_path.c_str())) { + if (allow_log_print) { + LogWarn("error removing file: %s, errno: %d", full_path.c_str(), errno); + } + closedir(dp); + return false; + } + } + } else { + // 无法获取属性,直接结束 + if (allow_log_print) { + LogWarn("error getting stat of: %s", full_path.c_str()); + } + closedir(dp); + return false; + } + } + closedir(dp); + + if (!is_reserve_dir) { + // 最后删除目录 + if (rmdir(dir.c_str())) { + if (allow_log_print) { + LogWarn("error removing directory: %s, errno: %d", dir.c_str(), errno); + } + return false; + } + } + + return true; } std::string Basename(const std::string &full_path) diff --git a/modules/util/fs.h b/modules/util/fs.h index 554d819..bd27977 100644 --- a/modules/util/fs.h +++ b/modules/util/fs.h @@ -195,14 +195,15 @@ bool IsDirectoryExist(const std::string &dir); bool MakeDirectory(const std::string &dir, bool allow_log_print = true); /** - * 删除目录 - * - * \param dir 目录 - * - * \return true 目录删除成功 - * \return false 目录删除失败 - */ -bool RemoveDirectory(const std::string &dir); + * @brief 删除目录 + * @param[in] const std::string & dir 需要删除的目录路径,路径需要全路径,如 /data/test + * @param[in] bool is_reserve_dir, 是否要保留目录,默认 false。如果为 true, 则保留整个目录树结构,只删除文件; + * 如果为 false,则删除整个目录 + * @param[in] bool allow_log_print,是否允许打印,默认 true。如果为 true,则允许打印内部出错信息; + * 如果为 false,则无日志输出 + * @return 目录删除成功返回 true,失败返回 false +*/ +bool RemoveDirectory(const std::string &dir, bool is_reserve_dir = false, bool allow_log_print = true); //////////////////////////////////////////////////////////////////// // 其它 -- Gitee From 644d507c0947132033765213f4846c95cb6f51a4 Mon Sep 17 00:00:00 2001 From: hfmlhk Date: Mon, 1 Apr 2024 14:39:18 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feature:=201.=E4=BB=A3=E7=A0=81=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E8=B0=83=E6=95=B4=202.=E6=96=B0=E5=A2=9E=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E7=9B=AE=E5=BD=95=E7=9A=84=E4=BD=86=E6=84=BF=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/util/fs.cpp | 25 +++++++++---------- modules/util/fs.h | 4 +-- modules/util/fs_test.cpp | 53 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/modules/util/fs.cpp b/modules/util/fs.cpp index 9716935..2b98e8a 100644 --- a/modules/util/fs.cpp +++ b/modules/util/fs.cpp @@ -256,7 +256,7 @@ bool MakeDirectory(const std::string &origin_dir_path, bool allow_log_print) } -bool RemoveDirectory(const std::string &dir, bool is_reserve_dir, bool allow_log_print) +bool RemoveDirectory(const std::string &dir, bool is_keep_dir, bool allow_log_print) { DIR *dp = opendir(dir.c_str()); if (dp == nullptr) { @@ -265,12 +265,13 @@ bool RemoveDirectory(const std::string &dir, bool is_reserve_dir, bool allow_log LogWarn("directory %s does not exist", dir.c_str()); } else { if (allow_log_print) { - LogWarn("error opening directory %s, errno: %d", dir.c_str(), errno); + LogWarn("open directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); } } return false; } + SetScopeExitAction([dp] { closedir(dp); }); struct dirent *entry; while ((entry = readdir(dp)) != nullptr) { std::string entry_name = entry->d_name; @@ -280,41 +281,37 @@ bool RemoveDirectory(const std::string &dir, bool is_reserve_dir, bool allow_log } // 依次查看每一个文件或者目录的属性 - std::string full_path = dir + "/" + entry_name; + std::string full_path = dir + '/' + entry_name; struct stat statbuf; if (!stat(full_path.c_str(), &statbuf)) { if (S_ISDIR(statbuf.st_mode)) { // 属性为目录,递归删除目录的内容 - if (!RemoveDirectory(full_path, is_reserve_dir, allow_log_print)) { - closedir(dp); + if (!RemoveDirectory(full_path, is_keep_dir, allow_log_print)) { return false; } } else { // 属性为文件,直接删除文件 - if (remove(full_path.c_str())) { + if (::remove(full_path.c_str())) { if (allow_log_print) { - LogWarn("error removing file: %s, errno: %d", full_path.c_str(), errno); + LogWarn("removing file %s fail, errno:%d, %s", full_path.c_str(), errno, strerror(errno)); } - closedir(dp); return false; } } } else { // 无法获取属性,直接结束 if (allow_log_print) { - LogWarn("error getting stat of: %s", full_path.c_str()); + LogWarn("getting state of %s fail, errno:%d, %s", full_path.c_str(), errno, strerror(errno)); } - closedir(dp); return false; } } - closedir(dp); - if (!is_reserve_dir) { + if (!is_keep_dir) { // 最后删除目录 - if (rmdir(dir.c_str())) { + if (::rmdir(dir.c_str())) { if (allow_log_print) { - LogWarn("error removing directory: %s, errno: %d", dir.c_str(), errno); + LogWarn("removing directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); } return false; } diff --git a/modules/util/fs.h b/modules/util/fs.h index bd27977..fbe820c 100644 --- a/modules/util/fs.h +++ b/modules/util/fs.h @@ -197,13 +197,13 @@ bool MakeDirectory(const std::string &dir, bool allow_log_print = true); /** * @brief 删除目录 * @param[in] const std::string & dir 需要删除的目录路径,路径需要全路径,如 /data/test - * @param[in] bool is_reserve_dir, 是否要保留目录,默认 false。如果为 true, 则保留整个目录树结构,只删除文件; + * @param[in] bool is_keep_dir, 是否要保留目录,默认 false。如果为 true, 则保留整个目录树结构,只删除文件; * 如果为 false,则删除整个目录 * @param[in] bool allow_log_print,是否允许打印,默认 true。如果为 true,则允许打印内部出错信息; * 如果为 false,则无日志输出 * @return 目录删除成功返回 true,失败返回 false */ -bool RemoveDirectory(const std::string &dir, bool is_reserve_dir = false, bool allow_log_print = true); +bool RemoveDirectory(const std::string &dir, bool is_keep_dir = false, bool allow_log_print = true); //////////////////////////////////////////////////////////////////// // 其它 diff --git a/modules/util/fs_test.cpp b/modules/util/fs_test.cpp index a4fa18b..e3a58f1 100644 --- a/modules/util/fs_test.cpp +++ b/modules/util/fs_test.cpp @@ -167,7 +167,6 @@ TEST(fs, MakeDirectory) { EXPECT_TRUE(MakeDirectory("a/b/c")); EXPECT_TRUE(IsFileExist("a/b/c")); ret = system("rm -rf a b"); - (void)ret; } TEST(fs, Dirname) { @@ -189,3 +188,55 @@ TEST(fs, Basename) { EXPECT_EQ(Basename(""), ""); } + +TEST(fs, RemoveDirectory) { + //! 绝对路径测试 + int ret = 0; + ret = system("rm -rf /tmp/fs_test_dir"); + ret = system("mkdir -p /tmp/fs_test_dir/first_dir"); + EXPECT_TRUE(WriteStringToTextFile("/tmp/fs_test_dir/fs_test_0_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("/tmp/fs_test_dir/fs_test_0_2.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("/tmp/fs_test_dir/first_dir/fs_test_1_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("/tmp/fs_test_dir/first_dir/fs_test_1_2.txt", "hello, this is a test file")); + EXPECT_TRUE(RemoveDirectory("/tmp/fs_test_dir/first_dir")); + + //! 相对路径测试 + EXPECT_TRUE(MakeDirectory("./a/b/c")); + EXPECT_TRUE(IsDirectoryExist("./a/b/c")); + EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/b/c/fs_test_c_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/b/c/fs_test_c_2.txt", "hello, this is a test file")); + EXPECT_TRUE(RemoveDirectory("./a/b/c")); + + //! 相对路径测试,一层目录 + EXPECT_TRUE(MakeDirectory("./a")); + EXPECT_TRUE(IsDirectoryExist("./a")); + EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file")); + EXPECT_TRUE(RemoveDirectory("./a")); + + //! 重复的'/' 测试 + EXPECT_TRUE(MakeDirectory("./a/b")); + EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file")); + EXPECT_TRUE(RemoveDirectory("./a//b")); + + //! 目录尾部多加一个 '/' 测试 + EXPECT_TRUE(MakeDirectory("./a/b")); + EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file")); + EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file")); + EXPECT_TRUE(RemoveDirectory("./a/b/")); + + // 只有目录,没有文件的删除测试 + EXPECT_TRUE(MakeDirectory("./a/b1/c")); + EXPECT_TRUE(MakeDirectory("./a/b2/c")); + EXPECT_TRUE(MakeDirectory("./a/b3/c")); + EXPECT_TRUE(RemoveDirectory("./a")); +} -- Gitee From fd707f408770d5429617fdc6f2dfac2501de1032 Mon Sep 17 00:00:00 2001 From: hfmlhk Date: Mon, 1 Apr 2024 15:06:08 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feature:=201.=E5=88=A0=E9=99=A4=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E5=87=BD=E6=95=B0=E4=BC=98=E5=8C=96=EF=BC=8C=E9=81=87?= =?UTF-8?q?=E5=88=B0=E9=94=99=E8=AF=AF=E7=BB=A7=E7=BB=AD=E5=88=A0=E9=99=A4?= =?UTF-8?q?=EF=BC=8C=E6=9C=80=E5=90=8E=E8=BF=94=E5=9B=9E=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E4=B8=8E=E5=90=A6=202.=E5=88=A0=E9=99=A4=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E6=A1=88=E4=BE=8B=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/util/fs.cpp | 17 +++++---- modules/util/fs_test.cpp | 81 ++++++++++++++++++++++------------------ 2 files changed, 55 insertions(+), 43 deletions(-) diff --git a/modules/util/fs.cpp b/modules/util/fs.cpp index 2b98e8a..7bdf99b 100644 --- a/modules/util/fs.cpp +++ b/modules/util/fs.cpp @@ -272,7 +272,10 @@ bool RemoveDirectory(const std::string &dir, bool is_keep_dir, bool allow_log_pr } SetScopeExitAction([dp] { closedir(dp); }); - struct dirent *entry; + + bool is_all_removed = true; + struct dirent *entry = nullptr; + while ((entry = readdir(dp)) != nullptr) { std::string entry_name = entry->d_name; if (entry_name == "." || entry_name == "..") { @@ -283,11 +286,11 @@ bool RemoveDirectory(const std::string &dir, bool is_keep_dir, bool allow_log_pr // 依次查看每一个文件或者目录的属性 std::string full_path = dir + '/' + entry_name; struct stat statbuf; - if (!stat(full_path.c_str(), &statbuf)) { + if (::stat(full_path.c_str(), &statbuf) == 0) { if (S_ISDIR(statbuf.st_mode)) { // 属性为目录,递归删除目录的内容 if (!RemoveDirectory(full_path, is_keep_dir, allow_log_print)) { - return false; + is_all_removed = false; } } else { // 属性为文件,直接删除文件 @@ -295,7 +298,7 @@ bool RemoveDirectory(const std::string &dir, bool is_keep_dir, bool allow_log_pr if (allow_log_print) { LogWarn("removing file %s fail, errno:%d, %s", full_path.c_str(), errno, strerror(errno)); } - return false; + is_all_removed = false; } } } else { @@ -303,7 +306,7 @@ bool RemoveDirectory(const std::string &dir, bool is_keep_dir, bool allow_log_pr if (allow_log_print) { LogWarn("getting state of %s fail, errno:%d, %s", full_path.c_str(), errno, strerror(errno)); } - return false; + is_all_removed = false; } } @@ -313,11 +316,11 @@ bool RemoveDirectory(const std::string &dir, bool is_keep_dir, bool allow_log_pr if (allow_log_print) { LogWarn("removing directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); } - return false; + is_all_removed = false; } } - return true; + return is_all_removed; } std::string Basename(const std::string &full_path) diff --git a/modules/util/fs_test.cpp b/modules/util/fs_test.cpp index e3a58f1..7f04297 100644 --- a/modules/util/fs_test.cpp +++ b/modules/util/fs_test.cpp @@ -167,6 +167,8 @@ TEST(fs, MakeDirectory) { EXPECT_TRUE(MakeDirectory("a/b/c")); EXPECT_TRUE(IsFileExist("a/b/c")); ret = system("rm -rf a b"); + + (void)ret; } TEST(fs, Dirname) { @@ -192,51 +194,58 @@ TEST(fs, Basename) { TEST(fs, RemoveDirectory) { //! 绝对路径测试 int ret = 0; - ret = system("rm -rf /tmp/fs_test_dir"); - ret = system("mkdir -p /tmp/fs_test_dir/first_dir"); - EXPECT_TRUE(WriteStringToTextFile("/tmp/fs_test_dir/fs_test_0_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("/tmp/fs_test_dir/fs_test_0_2.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("/tmp/fs_test_dir/first_dir/fs_test_1_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("/tmp/fs_test_dir/first_dir/fs_test_1_2.txt", "hello, this is a test file")); - EXPECT_TRUE(RemoveDirectory("/tmp/fs_test_dir/first_dir")); - - //! 相对路径测试 - EXPECT_TRUE(MakeDirectory("./a/b/c")); - EXPECT_TRUE(IsDirectoryExist("./a/b/c")); - EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/b/c/fs_test_c_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/b/c/fs_test_c_2.txt", "hello, this is a test file")); - EXPECT_TRUE(RemoveDirectory("./a/b/c")); + ret = ::system("rm -rf /tmp/fs_test_dir"); + ret = ::system("mkdir -p /tmp/fs_test_dir/first_dir"); + (void)ret; + WriteStringToTextFile("/tmp/fs_test_dir/fs_test_0_1.txt", "hello, this is a test file"); + WriteStringToTextFile("/tmp/fs_test_dir/fs_test_0_2.txt", "hello, this is a test file"); + WriteStringToTextFile("/tmp/fs_test_dir/first_dir/fs_test_1_1.txt", "hello, this is a test file"); + WriteStringToTextFile("/tmp/fs_test_dir/first_dir/fs_test_1_2.txt", "hello, this is a test file"); + EXPECT_TRUE(RemoveDirectory("/tmp/fs_test_dir")); + EXPECT_FALSE(IsDirectoryExist("/tmp/fs_test_dir")); //! 相对路径测试,一层目录 - EXPECT_TRUE(MakeDirectory("./a")); - EXPECT_TRUE(IsDirectoryExist("./a")); - EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file")); + MakeDirectory("./a"); + WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file"); + EXPECT_TRUE(RemoveDirectory("./a")); + EXPECT_FALSE(IsDirectoryExist("./a")); + + //! 相对路径测试,多层目录 + MakeDirectory("./a/b/c"); + WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/b/c/fs_test_c_1.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/b/c/fs_test_c_2.txt", "hello, this is a test file"); EXPECT_TRUE(RemoveDirectory("./a")); + EXPECT_FALSE(IsDirectoryExist("./a")); //! 重复的'/' 测试 - EXPECT_TRUE(MakeDirectory("./a/b")); - EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file")); + MakeDirectory("./a/b"); + WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file"); EXPECT_TRUE(RemoveDirectory("./a//b")); + EXPECT_FALSE(IsDirectoryExist("./a/b")); + EXPECT_TRUE(RemoveDirectory("./a/")); + EXPECT_FALSE(IsDirectoryExist("./a")); //! 目录尾部多加一个 '/' 测试 - EXPECT_TRUE(MakeDirectory("./a/b")); - EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file")); - EXPECT_TRUE(WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file")); - EXPECT_TRUE(RemoveDirectory("./a/b/")); + MakeDirectory("./a/b"); + WriteStringToTextFile("./a/fs_test_a_1.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/fs_test_a_2.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/b/fs_test_b_1.txt", "hello, this is a test file"); + WriteStringToTextFile("./a/b/fs_test_b_2.txt", "hello, this is a test file"); + EXPECT_TRUE(RemoveDirectory("./a/")); + EXPECT_FALSE(IsDirectoryExist("./a")); // 只有目录,没有文件的删除测试 - EXPECT_TRUE(MakeDirectory("./a/b1/c")); - EXPECT_TRUE(MakeDirectory("./a/b2/c")); - EXPECT_TRUE(MakeDirectory("./a/b3/c")); + MakeDirectory("./a/b1/c"); + MakeDirectory("./a/b2/c"); + MakeDirectory("./a/b3/c"); EXPECT_TRUE(RemoveDirectory("./a")); + EXPECT_FALSE(IsDirectoryExist("./a")); } -- Gitee From a35d54596b7fe0a852571f4c1a5bc3a55ff66b0c Mon Sep 17 00:00:00 2001 From: Hevake Lee Date: Mon, 1 Apr 2024 15:25:31 +0800 Subject: [PATCH 4/4] =?UTF-8?q?tidy:1.8.3,=20=E4=BC=98=E5=8C=96RemoveDirec?= =?UTF-8?q?tory()=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/util/fs.cpp | 27 +++++++++------------------ modules/util/fs.h | 17 +++++++++-------- modules/util/fs_test.cpp | 7 ++++++- version.mk | 2 +- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/modules/util/fs.cpp b/modules/util/fs.cpp index 7bdf99b..8e99969 100644 --- a/modules/util/fs.cpp +++ b/modules/util/fs.cpp @@ -255,18 +255,15 @@ bool MakeDirectory(const std::string &origin_dir_path, bool allow_log_print) return true; } - -bool RemoveDirectory(const std::string &dir, bool is_keep_dir, bool allow_log_print) +bool RemoveDirectory(const std::string &dir, bool is_remove_file_only) { - DIR *dp = opendir(dir.c_str()); + DIR *dp = ::opendir(dir.c_str()); if (dp == nullptr) { // 无法打开目录,直接结束 - if (errno == ENOENT && allow_log_print) { + if (errno == ENOENT) { LogWarn("directory %s does not exist", dir.c_str()); } else { - if (allow_log_print) { - LogWarn("open directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); - } + LogWarn("open directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); } return false; } @@ -289,33 +286,27 @@ bool RemoveDirectory(const std::string &dir, bool is_keep_dir, bool allow_log_pr if (::stat(full_path.c_str(), &statbuf) == 0) { if (S_ISDIR(statbuf.st_mode)) { // 属性为目录,递归删除目录的内容 - if (!RemoveDirectory(full_path, is_keep_dir, allow_log_print)) { + if (!RemoveDirectory(full_path, is_remove_file_only)) { is_all_removed = false; } } else { // 属性为文件,直接删除文件 if (::remove(full_path.c_str())) { - if (allow_log_print) { - LogWarn("removing file %s fail, errno:%d, %s", full_path.c_str(), errno, strerror(errno)); - } + LogWarn("removing file %s fail, errno:%d, %s", full_path.c_str(), errno, strerror(errno)); is_all_removed = false; } } } else { // 无法获取属性,直接结束 - if (allow_log_print) { - LogWarn("getting state of %s fail, errno:%d, %s", full_path.c_str(), errno, strerror(errno)); - } + LogWarn("getting state of %s fail, errno:%d, %s", full_path.c_str(), errno, strerror(errno)); is_all_removed = false; } } - if (!is_keep_dir) { + if (!is_remove_file_only) { // 最后删除目录 if (::rmdir(dir.c_str())) { - if (allow_log_print) { - LogWarn("removing directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); - } + LogWarn("removing directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); is_all_removed = false; } } diff --git a/modules/util/fs.h b/modules/util/fs.h index fbe820c..c030991 100644 --- a/modules/util/fs.h +++ b/modules/util/fs.h @@ -195,15 +195,16 @@ bool IsDirectoryExist(const std::string &dir); bool MakeDirectory(const std::string &dir, bool allow_log_print = true); /** - * @brief 删除目录 - * @param[in] const std::string & dir 需要删除的目录路径,路径需要全路径,如 /data/test - * @param[in] bool is_keep_dir, 是否要保留目录,默认 false。如果为 true, 则保留整个目录树结构,只删除文件; - * 如果为 false,则删除整个目录 - * @param[in] bool allow_log_print,是否允许打印,默认 true。如果为 true,则允许打印内部出错信息; - * 如果为 false,则无日志输出 - * @return 目录删除成功返回 true,失败返回 false + * 递归删除指定目录 + * 等价于shell命令:"rm -rf xxx" + * + * \param dir 需要删除的目录路径,路径需要全路径,如 /data/test + * \param is_remove_file_only 保存目录结构,仅删除文件 + * + * \return true 目录被完全删除 + * \return false 目录未被完全删除 */ -bool RemoveDirectory(const std::string &dir, bool is_keep_dir = false, bool allow_log_print = true); +bool RemoveDirectory(const std::string &dir, bool is_remove_file_only = false); //////////////////////////////////////////////////////////////////// // 其它 diff --git a/modules/util/fs_test.cpp b/modules/util/fs_test.cpp index 7f04297..0ab8c4a 100644 --- a/modules/util/fs_test.cpp +++ b/modules/util/fs_test.cpp @@ -197,11 +197,16 @@ TEST(fs, RemoveDirectory) { ret = ::system("rm -rf /tmp/fs_test_dir"); ret = ::system("mkdir -p /tmp/fs_test_dir/first_dir"); (void)ret; + WriteStringToTextFile("/tmp/fs_test_dir/fs_test_0_1.txt", "hello, this is a test file"); WriteStringToTextFile("/tmp/fs_test_dir/fs_test_0_2.txt", "hello, this is a test file"); WriteStringToTextFile("/tmp/fs_test_dir/first_dir/fs_test_1_1.txt", "hello, this is a test file"); WriteStringToTextFile("/tmp/fs_test_dir/first_dir/fs_test_1_2.txt", "hello, this is a test file"); - EXPECT_TRUE(RemoveDirectory("/tmp/fs_test_dir")); + + EXPECT_TRUE(RemoveDirectory("/tmp/fs_test_dir", true)); //! 仅删文件,不删目录 + EXPECT_TRUE(IsDirectoryExist("/tmp/fs_test_dir/first_dir/")); + + EXPECT_TRUE(RemoveDirectory("/tmp/fs_test_dir", false)); //! 全部删除 EXPECT_FALSE(IsDirectoryExist("/tmp/fs_test_dir")); //! 相对路径测试,一层目录 diff --git a/version.mk b/version.mk index 3ad48fb..59d90f4 100644 --- a/version.mk +++ b/version.mk @@ -1,4 +1,4 @@ # TBOX版本号 TBOX_VERSION_MAJOR := 1 TBOX_VERSION_MINOR := 8 -TBOX_VERSION_REVISION := 2 +TBOX_VERSION_REVISION := 3 -- Gitee