#ifndef _FY_FILES_HPP_ #define _FY_FILES_HPP_ #include #include #include #include #include #include #include #include #include #include "base/strings.hpp" #include "base/os.hpp" #include "utils/Log.h" namespace base { inline bool remove(const char* file) { return unlink(file) == 0; } //文件存在返回真,否则假 inline bool exists(const char* path) { if (path == NULL) { return false; } if (access(path, F_OK) == 0) { return true; } return false; } inline bool write_all(const std::string& file_path, const std::string& content) { std::ofstream ofs(file_path.c_str(), std::ios::binary | std::ios::out); if (!ofs.is_open()) { return false; } ofs << content; ofs.flush(); return ofs.good(); } inline std::string read_all(const std::string& file) { std::ifstream ifs(file, std::ios::binary | std::ios::in); if (!ifs.is_open()) { return ""; } std::stringstream ss; ss << ifs.rdbuf(); return ss.str(); } // 文件大小 inline int64_t size_of(const std::string &file) { long filesize = -1; struct stat statbuff; if(stat(file.c_str(), &statbuff) < 0){ return filesize; } else { filesize = statbuff.st_size; } return filesize; } inline int copy_file(const std::string &source, const std::string &target, void *user_data, void (*progress)(const void* user_data, int64_t now, int64_t all)) { if (!exists(source.c_str())) { LOGE("%s file not exist", source.c_str()); return -1; } FILE* in = fopen(source.c_str(), "rb"); if (in == NULL) { LOGE("failed to open file %s", source.c_str()); return -2; } FILE* out = fopen(target.c_str(), "wb"); if (out == NULL) { LOGE("failed to create file %s", target.c_str()); return -3; } int64_t all = size_of(source.c_str()); if (all < 0) { LOGE("unknown file size"); return -4; } int64_t now = 0; char buf[4096] = {0}; int read_ret = 0; int write_ret = 0; if (progress) { progress(user_data, now, all); } while (!feof(in)) { read_ret = fread(buf, 1, int(sizeof(buf)), in); if (read_ret < 0) { fclose(in); fclose(out); LOGE("failed to read %s", source.c_str()); return -5; } write_ret = fwrite(buf, 1, read_ret, out); if (write_ret != read_ret) { fclose(in); fclose(out); LOGE("failed to write %s", target.c_str()); return -6; } now += write_ret; if (progress) { progress(user_data, now, all); } } if (now != all) { LOGE("copy_file failed"); return -7; } fflush(out); fclose(in); fclose(out); return 0; } inline bool _match(const std::string &str, const std::string &pattern) { if (pattern.compare("*") == 0) { return true; } std::string::size_type pos = pattern.find("*"); //*.mp3 if (pos == 0) { return endswith(str, pattern.substr(1, pattern.size() - 1)); } else if (pos == (pattern.size() - 1)) { return startswith(str, pattern.substr(0, pattern.size() - 1)); } return true; } inline std::vector list(const std::string &path, const std::string &pattern, bool recursive) { std::vector ret; DIR *d; struct dirent *entry; if ((d = opendir(path.c_str())) == NULL) { //can't open dir return ret; } while ((entry = readdir(d)) != NULL) { if ((strcmp(".", entry->d_name) == 0) || (strcmp("..", entry->d_name) == 0)) { continue; } if ((entry->d_type == DT_DIR) && recursive) { std::vector sub = list(base::path::join(path, entry->d_name), pattern, recursive); ret.insert(ret.end(), sub.begin(), sub.end()); } else { if (!_match(entry->d_name, pattern)) { continue; } ret.push_back(base::path::join(path, entry->d_name)); } } closedir(d); return ret; } } /* namespace base */ #endif /* _FY_FILES_HPP_ */