对文件和文件夹的操作是日常开发中比较高频的操作,这里简单罗列几种高频的使用方法,如文件是否存在、级联创建文件夹、文件大小等等
#include <fstream>
#include <sys/stat.h>
#include <dirent.h>
#include "FileUtils.h"
/**
* 判断文件是否存在
*/
bool FileUtils::isExist(const std::string &path) {
std::ifstream is(path);
bool isGood = is.good();
is.close();
return isGood;
}
/**
* 获取一个路径的父目录
*/
std::string FileUtils::parentPath(const std::string &path) {
auto position = path.find_last_of('/');
// 找不到分隔符,返回空
if (position == std::string::npos) {
return "";
}
// 去掉最后一个'/'之后的其他字符
auto temp = path.substr(0, position);
// 如果最后一个字符是'/',去掉'/'后再找
if (position == path.size() - 1) {
return parentPath(temp);
}
return temp;
}
/**
* 级联创建文件夹目录
*/
bool FileUtils::createDirectory(const std::string &path) {
if (isExist(path)) {
return true;
}
if (path.empty()) {
return false;
}
// 逐级判断父目录是否存在,不存在创建父目录
auto parent = parentPath(path);
if (!isExist(parent)) {
if (!createDirectory(parent)) {
return false;
}
}
int code = mkdir(path.c_str(), 0777);
return (code == 0);
}
/**
* 获取文件大小,字节数
*/
int FileUtils::getFileSize(std::string path) {
#ifdef UNIX
struct stat buf;//文件字节数
int res = stat(path.c_str(), &buf);
if (res != 0) {
return 0;
} else {
return buf.st_size;
}
#elif WIN32
struct _stat info;
if(_stat(path.c_str(), &info) == 0)
{
return info.st_size;
}
#endif
return 0;
}
/**
* 删除一个文件。
*/
bool FileUtils::deleteFile(const std::string &path) {
if (!isExist(path)) {
return true;
}
int code = remove(path.c_str());
return (code == 0);
}
/**
* 获取文件的名称
* @param path 文件路径
* @return
*/
std::string FileUtils::getFileName(const std::string &path) {
if (path.empty()) {
return "";
}
auto position = path.find_last_of('/');
// 找不到分隔符,返回空
if (position == std::string::npos) {
return path;
}
// 路径的最后一个字符就是 '/'
if (position == path.size() - 1) {
return "";
}
// 最后一个'/' 之后的所有字符
auto temp = path.substr(position + 1);
return temp;
}
/**
* 判断路径是否为一个文件夹
*/
bool FileUtils::isDirectory(const std::string &path) {
if (!isExist(path)) {
return false;
}
struct stat buffer{};
int code = stat(path.c_str(), &buffer);
if (code != 0) {
return false;
}
bool isDir = S_ISDIR(buffer.st_mode);
return isDir;
}
/**
* 获取子文件夹目录
*/
std::vector<std::string> FileUtils::getSubFiles(const std::string &directory, bool returnAbsolutePath) {
std::vector<std::string> res;
if (!isDirectory(directory)) {
return res;
}
struct dirent *ptr;
DIR *dir = opendir(directory.c_str());
while ((ptr = readdir(dir)) != nullptr) {
std::string name = ptr->d_name;
if (name == std::string(".") || name == std::string("..")) {
continue;
}
if (returnAbsolutePath) {
res.emplace_back(join(directory, name));
} else {
res.emplace_back(name);
}
}
closedir(dir);
return res;
}
/**
* 拼接路径
*/
std::string FileUtils::join(const std::string &parent, const std::string &name) {
if (parent.empty()) {
return name;
}
auto size = parent.size();
char lastChar = parent.at(size - 1);
char firstChar = name.at(0);
// 两个都没有 '/'
if (lastChar != '/' && firstChar != '/') {
return parent + "/" + name;
}
// 有一个 '/'
else if (lastChar == '/' || firstChar == '/') {
return parent + name;
}
// 有两个 '/'
else {
return parent + name.substr(1);
}
}