#pragma once #include "noncopyable.hpp" struct ACL_SCAN_DIR; namespace acl { class string; class ACL_CPP_API scan_dir : public noncopyable { public: scan_dir(void); virtual ~scan_dir(void); /** * 打开目录 * @param path {const char*} 目录路径,非空指针 * @param recursive {bool} 是否允许递归扫描目录 * @param rmdir_on {bool} 当目录为空时,是否需要删除该空目录 * @return {bool} 打开目录是否成功 */ bool open(const char* path, bool recursive = true, bool rmdir_on = false); /** * 虚方法,当需要删除空目录时,子类可以实现此虚方法来删除传入的目录, * 本虚方法内部会自动调用 rmdir 删除空目录 * @param path {const char*} 需要被删除的空目录 * @return {bool} 删除目录是否成功 */ virtual bool rmdir_callback(const char* path); /** * 关闭目录,同时释放内部资源 */ void close(void); /** * 扫描下一个文件(遇到目录会自动跳过),当在 open 指定了允许递归扫描选项 * (即 recursive = true),则该函数会递归扫描所打开目录的所有子目录 * @param full {bool} 是否需要返回文件全路径 * @return {const char*} 非 NULL 表示所扫描到的文件名,否则表示扫描完毕 * 或目录还未打开 */ const char* next_file(bool full = false); /** * 扫描下一个目录(遇到文件或 "." 或 ".." 会跳过),当在 open 指定允许了 * 允许递归扫描项(即 recursive = true),则该函数会递归扫描所开目录的所 * 有子目录 * @param full {bool} 是否需要返回目录全路径 * @return {const char*} 非 NULL 表示所扫描到的目录名,否则表示扫描完 * 毕或目录还未打开 */ const char* next_dir(bool full = false); /** * 扫描下一个目录或文件,当在 open 指定了允许递归扫描项(即 resursive * = true),则该函数会递归扫描所打开目录的所有子目录及文件 * @param full {bool} 是否需要返回目录或文件的全路径,如果为 true 则返 * 回全路径,否则只返回文件名或目录名且都不含路径 * @param is_file {bool*} 当返回结果非空时,该地址存储的值表示所扫描到 * 的是否是文件,如果为 true 则为文件,否则为目录 * @return {const char*} 非 NULL 表示所扫描到的目录名或文件名,否则表 * 示扫描完毕或目录还未打开 */ const char* next(bool full = false, bool* is_file = NULL); /** * 获得当前扫描过程所在的目录路径,返回的路径尾部不包含路径分隔符 '/' * 或 '\\' (win32),如对于路径:/home/zsx/,则会返回 /home/zsx,如果 * 路径为根路径:/ 则该 '/' 将会保留;在 _WIN32 下,返回类似于 * C:\Users\zsx 的路径 * @return {const char*} 当目录打开时该函数返回非空指针,否则返回 NULL */ const char* curr_path(); /** * 获得当前程序扫描过程所扫到的文件名 * @param full {bool} 是否需要同时返回文件全路径 * @return {bool} 如果目录未找开或当前扫描的不是文件,则返回 NULL */ const char* curr_file(bool full = false); /** * 返回当前已经扫描的目录的个数 * @return {size_t} */ size_t dir_count() const; /** * 返回当前已经扫描的文件的个数 * @return {size_t} */ size_t file_count() const; #if defined(_WIN32) || defined(_WIN64) /** * 获得当前已经扫描的文件及目录大小的总和 * @return {acl_uint64} */ unsigned __int64 scaned_size() const; /** * open 成功后调用本函数统计根目录下所有文件及目录大小的总和 * @param nfiles {int*} 非空时存储被删除的文件个数 * @param ndirs {int*} 非空时存储被删除的目录个数 * @return {acl_uint64} 根目录下所有文件及目录大小的总和 */ unsigned __int64 all_size(int* nfiles = NULL, int* ndirs = NULL) const; /** * 根目录下所有文件及目录大小的总和 * @param path {const char*} 需要被删除的根目录 * @param recursive {bool} 是否递归扫描所有目录 * @param nfiles {int*} 非空时存储被删除的文件个数 * @param ndirs {int*} 非空时存储被删除的目录个数 * @return {acl_uint64} 根目录下所有文件及目录大小的总和 */ static unsigned __int64 all_size(const char* path, bool recursive = true, int* nfiles = NULL, int* ndirs = NULL); /** * open 成功后调用本函数删除根目录下的所有文件及目录 * @param nfiles {int*} 非空时存储被删除的文件个数 * @param ndirs {int*} 非空时存储被删除的目录个数 * @return {acl_unint64} 删除的所有文件及目录大小总和(字节单位) */ unsigned __int64 remove_all(int* nfiles = NULL, int* ndirs = NULL) const; /** * 删除根目录下的所有文件及目录 * @param path {const char*} 需要被删除的根目录 * @param recursive {bool} 是否递归扫描所有目录 * @param nfiles {int*} 非空时存储被删除的文件个数 * @param ndirs {int*} 非空时存储被删除的目录个数 * @return {acl_unint64} 删除的所有文件及目录大小总和(字节单位) */ static unsigned __int64 remove_all(const char* path, bool recursive = true, int* nfiles = NULL, int* ndirs = NULL); #else unsigned long long scaned_size() const; unsigned long long all_size(int* nfiles = NULL, int* ndirs = NULL) const; static unsigned long long all_size(const char* path, bool recursive = true, int* nfiles = NULL, int* ndirs = NULL); unsigned long long remove_all(int* nfiles = NULL, int* ndirs = NULL) const; static unsigned long long remove_all(const char* path, bool recursive = true, int* nfiles = NULL, int* ndirs = NULL); #endif /** * 获得当前程序运行的路径 * @param out {string&} 存储结果 * @return {bool} 是否成功获得当前程序运行路径 */ static bool get_cwd(string& out); public: ACL_SCAN_DIR* get_scan_dir(void) const { return scan_; } /** * 设置回调方法,用来删除空目录 * @param fn {int (*)(ACL_SCAN_DIR*, const char*, void*)} * @param ctx {void*} */ void set_rmdir_callback(int (*fn)(ACL_SCAN_DIR*, const char*, void*), void* ctx); private: char* path_; ACL_SCAN_DIR* scan_; string* path_buf_; string* file_buf_; static int rmdir_def(ACL_SCAN_DIR* scan, const char* path, void* ctx); }; } // namespace acl