共计 7479 个字符,预计需要花费 19 分钟才能阅读完成。
文件操作相干
#pragma once
#include <stdio.h>
#include <malloc.h>
#include <string>
#include <direct.h> // 操作目录相干
#include <functional>
#include <fstream>
#include <vector>
#include <sstream>
#include <Windows.h>
#include <sys/stat.h>
#include "String.hpp"
namespace File {
// 创立文件
bool Create(const std::string& filename);
// 删除文件
bool Delete(const std::string& filename);
// 判断文件是否存在
bool Exists(const std::string& filename);
// 文件挪动或者改名
bool Move(const std::string& oldname, const std::string& newname);
// 读取文件并 out 返回
void ReadFile(const std::string& filename, std::string& outData);
// 写入文件
void WriteFile(const std::stringstream& data, const std::string& filename);
}
namespace Path {
// 本人写的文件监控类
class FileWatcher {
private:
std::string math = "*.*";
std::string path;
std::function<void(const std::string& filename)> callback = NULL;
size_t sleep;
bool ctn = true;
void TaskFunc();
public:
FileWatcher(const std::string& path, const std::string& math, const std::function<void(const std::string& filename)>& callback, size_t sleep = 500);
~FileWatcher();};
// 创立门路 MultiDir: 是否创立多级目录
bool Create(const std::string& path);
// 删除门路 如果存在子文件夹或者文件 将会递归删除
bool Delete(const std::string& directoryName);
// 通配符搜寻文件
std::vector<std::string> SearchFiles(const std::string& path, const std::string& pattern);
// 查看门路是否存在
bool Exists(const std::string& path);
// 获取文件名称 (文件名称)
std::string GetFileNameWithoutExtension(const std::string& _filename);
// 获取文件目录名称 (所在目录)
std::string GetDirectoryName(const std::string& _filename);
// 获取文件名称 + 后缀
std::string GetFileName(const std::string& _filename);
// 获取文件后缀名 (后缀名)
std::string GetExtension(const std::string& _filename);
// 获取过程所在绝对路径目录
std::string StartPath();
// 获取过程所在绝对路径 Fullpath
std::string GetModuleFileName();}
namespace FileSystem {
typedef enum :unsigned char {
None,
File,
Directory
}FileType;
struct FileInfo
{
private:
std::ifstream* fs = NULL;
public:
unsigned long long StreamPos = 0;
struct _stat64 __stat;
FileType FileType = FileSystem::FileType::None;
std::string Extension;
std::string FullName;
std::string FileName;
bool ReadOnly = false;
size_t Read(char* _buf_, size_t _rdCount = 512) {
size_t rdbufCount = _rdCount;
if (StreamPos + _rdCount >= __stat.st_size) {rdbufCount = __stat.st_size - StreamPos;}
if (rdbufCount == 0) {return 0;}
if (fs == NULL) {fs = new std::ifstream(FullName, std::ios::binary);
}
fs->seekg(StreamPos);
fs->read(_buf_, rdbufCount);
StreamPos += rdbufCount;
return rdbufCount;
}
FileInfo() {}
FileInfo(const std::string& filename) {int status = _stat64(filename.c_str(), &__stat);
if (status == 0 && (__stat.st_mode & S_IFREG) == S_IFREG) {Extension = Path::GetExtension(filename);
FileName = Path::GetFileName(filename);
FullName = filename;
FileType = FileType::File;
}
}
void Close() {if (fs) {fs->close();
delete fs;
fs = NULL;
}
}
~FileInfo() {if (fs) {fs->close();
delete fs;
}
}
};
void ReadFileInfoWin32(const std::string& directory, WIN32_FIND_DATAA& pNextInfo, std::vector<FileSystem::FileInfo>& result);
size_t Find(const std::string& directory, std::vector<FileSystem::FileInfo>& result, const std::string& pattern = "*.*");
}
// 定义....................................................................................................................
namespace FileSystem {inline size_t Find(const std::string& directory, std::vector<FileSystem::FileInfo>& result, const std::string& pattern) {
HANDLE hFile = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAA pNextInfo;
hFile = FindFirstFileA((directory + "\\" + pattern).c_str(), &pNextInfo);
if (INVALID_HANDLE_VALUE == hFile)
{return 0;}
if (pNextInfo.cFileName[0] != '.') {ReadFileInfoWin32(directory, pNextInfo, result);
}
while (FindNextFileA(hFile, &pNextInfo))
{if (pNextInfo.cFileName[0] != '.') {ReadFileInfoWin32(directory, pNextInfo, result);
}
}
FindClose(hFile);// 防止内存透露
return result.size();};
};
namespace File {
#ifdef _WINDEF_
inline bool Exists(const std::string& filename) {DWORD dwAttr = GetFileAttributesA(filename.c_str());
if (dwAttr == DWORD(-1)) {return false;}
if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) {return true;}
return false;
}
#else
// 用 stat 函数在 windows 环境下可能会呈现问题
inline bool Exists(const std::string& filename) {
struct stat buf;
int status = stat(filename.c_str(), &buf);
if (status == 0 && (buf.st_mode & S_IFREG) == S_IFREG) {return true;}
else {return false;}
}
#endif
inline bool Create(const std::string& filename) {File::Delete(filename);
std::ofstream ofs(filename.c_str(), std::ios::app);
ofs.flush();
ofs.close();
return true;
}
inline std::string ReadFile(const std::string& filename) {
std::stringstream ss;
std::ifstream ifs(filename, std::ios::binary);
ss << ifs.rdbuf();
return ss.str();}
inline bool Delete(const std::string& filename) {::remove(filename.c_str());
return !File::Exists(filename);
}
inline bool Move(const std::string& oldname, const std::string& newname) {if (!File::Delete(newname)) {printf("Move Faild ! The target file is in use\n");
return false;
}
int code = ::rename(oldname.c_str(), newname.c_str());
if (File::Exists(oldname)) {return false;}
return true;
}
inline void ReadFile(const std::string& filename, std::string& outData) {outData.clear();
std::ifstream* ifs = new std::ifstream(filename.c_str(), std::ios::binary);
std::stringstream ss;
ss << ifs->rdbuf();
ifs->close();
outData = ss.str();
delete ifs;
}
inline void WriteFile(const std::stringstream& data, const std::string& filename)
{std::string buf = data.str();
File::Delete(filename);
std::ofstream* ofs = new std::ofstream(filename, std::ios::binary);
ofs->write(buf.c_str(), buf.size());
ofs->flush();
ofs->close();
delete ofs;
}
};
namespace Path {inline void FileWatcher::TaskFunc()
{
std::vector<std::string> files;// 启动加载以后文件
//std::vector<std::string> files = Path::SearchFiles(path, math.c_str());
for (; exit;)
{
// 移除不存在的文件
for (size_t i = 0; i < files.size(); i++)
{if (!File::Exists(files[i]))
{std::vector<std::string>::iterator it = std::find(files.begin(), files.end(), files[i]);
if (it != files.end()) {files.erase(it);
}
}
}
// 判断是否新增的文件 s
std::vector<std::string> tmp = Path::SearchFiles(path, math.c_str());
for (auto& item : tmp)
{if (find(files.begin(), files.end(), item) == files.end())
{files.push_back(item);
if (callback) {callback(item);
}
}
}
// 值越小越精准
Sleep(sleep);
}
}
inline FileWatcher::FileWatcher(const std::string& path, const std::string& math, const std::function<void(const std::string& filename)>& callback, size_t sleep)
{
this->sleep = sleep;
this->callback = callback;
this->path = path;
this->math = math;
TaskFunc();}
inline FileWatcher::~FileWatcher()
{ctn = false;}
inline bool Delete(const std::string& directoryName) {
std::vector<FileSystem::FileInfo>result;
FileSystem::Find(directoryName, result);
for (auto& it : result) {if (it.FileType == FileSystem::FileType::File) {File::Delete(it.FullName);
}
if (it.FileType == FileSystem::FileType::Directory) {Path::Delete(it.FullName);
}
}
::_rmdir(directoryName.c_str());
return !Path::Exists(directoryName);
}
#ifdef _WINDEF_
inline bool Exists(const std::string& path) {DWORD dwAttr = GetFileAttributesA(path.c_str());
if (dwAttr == DWORD(-1)) {return false;}
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
{return true;}
return false;
}
#else
//XP 零碎下判断可能会有问题
inline bool Exists(const std::string& path)
{
struct stat buf;
int status = stat(path.c_str(), &buf);
if (status == 0) {return true;}
return false;
}
#endif
inline std::string GetFileNameWithoutExtension(const std::string& _filename) {std::string newDir = String(_filename).Replace("\\", "/");
int bPos = newDir.rfind("/");
int ePos = newDir.rfind(".");
newDir = newDir.substr(bPos + 1, ePos - bPos - 1);
return newDir;
}
inline std::string GetExtension(const std::string& _filename) {size_t pos = _filename.rfind(".");
return pos == size_t(-1) ? "" : _filename.substr(pos);
}
inline std::string GetDirectoryName(const std::string& _filename) {int pos = String(_filename).Replace("\\", "/").rfind("/");
return _filename.substr(0, pos);
}
inline std::string GetFileName(const std::string& filename) {return Path::GetFileNameWithoutExtension(filename) + Path::GetExtension(filename);
}
inline std::string StartPath() {return Path::GetDirectoryName(GetModuleFileName());
}
inline std::string GetModuleFileName() {CHAR exeFullPath[MAX_PATH];
::GetModuleFileNameA(NULL, exeFullPath, MAX_PATH);
std::string filename = exeFullPath;
return filename;
}
}
正文完