关于工具:工具函数记录

38次阅读

共计 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;
    }
}

正文完
 0