栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C++模块实现】| 【03】文件管理模块

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C++模块实现】| 【03】文件管理模块

文章目录
    • 参考内容
    • 实现

该模块是从sylar服务器框架中学习的,以下将会对其进行总结以加深对该框架的理解;

========》视频地址《========

参考内容

========》Linux系统编程 | 【02】文件I/O操作常用函数介绍《========

========》【C++】| 如何更好的利用do……while(0)《========

========》ifstream《=========

实现
class FSUtil {
public:
    
    static void ListAllFile(std::vector& files
                            , const std::string& path
                            , const std::string& subfix);
    
    static bool Mkdir(const std::string& dirname);
    
    static bool IsRunningPidfile(const std::string& pidfile);
    
    static bool Rm(const std::string& path);
    
    static bool Mv(const std::string& from, const std::string& to);
    
    static bool Realpath(const std::string& path,std::string& rpath);
    
    static bool Symlink(const std::string& frm, const std::string& to);
    
    static bool Unlink(const std::string& filename, bool exist= false);
    static std::string Dirname(const std::string& filename);
    static std::string Basename(const std::string& filename);
    static bool OpenForRead(std::ifstream& ifs, const std::string& filename
                            , std::ios_base::openmode mode);
    static bool OpenForWrite(std::ofstream& ofs, const std::string& filename
                            , std::ios_base::openmode mode);
};
void FSUtil::ListAllFile(std::vector& files
                            , const std::string& path
                            , const std::string& subfix) {
    
    if(access(path.c_str(), 0) != 0)
        return;
    
    DIR* dir = opendir(path.c_str());
    if(dir == nullptr)
        return;

    struct dirent* dp = nullptr;
    
    while ((dp = readdir(dir)) != nullptr) {
        
        if(dp->d_type == DT_DIR) {
            if(!strcmp(dp->d_name, "..")
                || !strcmp(dp->d_name, "."))
                continue;       // 若该文件为该两者,则直接跳过
            ListAllFile(files, path + "/" + dp->d_name, subfix);    // 递归执行
        
        }else if(dp->d_type == DT_REG) {
            std::string filename(dp->d_name);
            if(subfix.empty()) {    // 若没有指定文件后缀
                files.push_back(path + "/" + filename);
            }else {
                
                if(filename.size() < subfix.size()) {
                    continue;
                }
                if(filename.substr(filename.length() - subfix.size()) == subfix) {
                    files.push_back(path + "/" + filename);
                }
            }
        }
    }
    closedir(dir);
}


static int __lstat(const char* file, struct stat* st = nullptr) {
    struct stat lst;
    int ret = lstat(file, &lst);
    if(st) {
        *st = lst;
    }

    return ret;
}


static int __mkdir(const char* dirname) {
    
    if(access(dirname, F_OK) == 0) {
        return 0;
    }
    return mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
}


bool FSUtil::Mkdir(const std::string& dirname) {
    
    if(__lstat(dirname.c_str()) == 0) {
        return true;
    }
    char* path = strdup(dirname.c_str());   // 获取一个新串副本
    char* ptr = strchr(path + 1, '/');  // 获取第一个出现/字符的位置
    
    do {
        for(; ptr; *ptr = '/', ptr = strchr(ptr + 1, '/')) {
            *ptr = '';
            if(__mkdir(path) != 0) {    // 创建文件夹
                break;
            }
        }
        if(ptr != nullptr) {
            break;
        }else if(__mkdir(path) != 0) {
            break;
        }
        free(path);
        return true;
    } while (0);
    free(path);

    return false;
}

bool FSUtil::IsRunningPidfile(const std::string& pidfile) {
    if(__lstat(pidfile.c_str()) != 0) {
        return false;
    }
    std::ifstream ifs(pidfile);
    std::string line;
    if(!ifs || !std::getline(ifs, line)) {
        return false;
    }
    if(line.empty()) {
        return false;
    }
    pid_t pid = atoi(line.c_str());
    if(pid <= 1) {
        return false;
    }
    if(kill(pid, 0)) {
        return false;
    }

    return true;
}


bool FSUtil::Symlink(const std::string& frm, const std::string& to) {
    if(!Rm(to)) {
        return false;
    }
    return ::symlink(frm.c_str(), to.c_str());
}


bool FSUtil::Unlink(const std::string& filename, bool exist) {
    if(!exist && __lstat(filename.c_str())) {
        return true;
    }
    return ::unlink(filename.c_str()) == 0;
}


bool FSUtil::Rm(const std::string& path) {
    struct stat st;
    if(lstat(path.c_str(), &st)) {
        return true;
    }
    if(!(st.st_mode & S_IFDIR)) {
        return Unlink(path);
    }

    DIR* dir = opendir(path.c_str());
    if(!dir) {
        return false;
    }

    bool ret = true;
    struct dirent* dp = nullptr;
    while((dp = readdir(dir))) {
        if(!strcmp(dp->d_name, ".")
           || !strcmp(dp->d_name, "..")) {
            continue;
        }
        std::string dirname = path + "/" + dp->d_name;
        ret = Rm(dirname);
    }
    closedir(dir);
    if(::rmdir(path.c_str())) {
        ret = false;
    }
    return ret;
}


bool FSUtil::Mv(const std::string& from, const std::string& to) {
    if(!Rm(to)) {
        return false;
    }
    return rename(from.c_str(), to.c_str()) == 0;
}


bool FSUtil::Realpath(const std::string& path, std::string& rpath) {
    if(__lstat(path.c_str())) {
        return false;
    }
    char* ptr = ::realpath(path.c_str(), nullptr);
    if(nullptr == ptr) {
        return false;
    }
    std::string(ptr).swap(rpath);
    free(ptr);

    return true;
}


bool FSUtil::OpenForRead(std::ifstream& ifs, const std::string& filename
                        , std::ios_base::openmode mode) {
    ifs.open(filename.c_str(), mode);

    return ifs.is_open();
}

bool FSUtil::OpenForWrite(std::ofstream& ofs, const std::string& filename
        , std::ios_base::openmode mode) {
    ofs.open(filename.c_str(), mode);
    if(!ofs.is_open()) {
        std::string dir = Dirname(filename);
        Mkdir(dir);
        ofs.open(filename.c_str(), mode);
    }
    return ofs.is_open();
}


std::string FSUtil::Dirname(const std::string& filename) {
    if(filename.empty()) {
        return ".";
    }
    auto pos = filename.rfind('/');
    if(pos == 0) {
        return "/";
    }else if(pos == std::string::npos) {
        return ".";
    }else {
        return filename.substr(0, pos);
    }
}


std::string FSUtil::Basename(const std::string& filename) {
    if(filename.empty()) {
        return filename;
    }
    auto pos = filename.rfind('/');
    if(pos == std::string::npos) {
        return filename;
    }else {
        return filename.substr(pos + 1);
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025835.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号