文件工具类(一)

首先文件压缩类的实列采用的是单列模式

单例类模板

cpp 复制代码
template <class T>
class Singleton {
private:
    Singleton() = default;

public:
    ~Singleton() = default;
    Singleton(const Singleton &) = delete;
    Singleton &operator=(const Singleton &) = delete;

    Singleton(const Singleton &&) = delete;
    Singleton &operator=(Singleton &&) = delete;
    static T *instance() {
        static T instance = T();
        return &instance;
    }
    friend T;
};

filehelper继承这个类然后友员声明,表示只有这一个实列并且允许模板类 Singleton<FileHelper> 访问 FileHelper 的私有成员(包括私有构造函数)。

cpp 复制代码
class FileHelper : public QObject, public Singleton<FileHelper> {
    Q_OBJECT
    friend class Singleton<FileHelper>;

判断传入字符串是否是一个有效字符串函数

将传入的字符串用qurl::fromuserinput转换为qurl,返回是否有效。

cpp 复制代码
 static bool isValidUrl(const QString &input) {
        QUrl const url = QUrl::fromUserInput(input);
        return url.isValid();
    }

获取当前系统的桌面绝对路径

cpp 复制代码
Q_INVOKABLE static QString desktopPath() {
        return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    }

获取当前系统桌面的url

cpp 复制代码
    Q_INVOKABLE static QUrl desktop() {
        return QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
    }

获取文件名函数

cpp 复制代码
Q_INVOKABLE static QString getFileName(const QUrl &filePath) {
        spdlog::debug("getFileName: {}", filePath.toLocalFile().toUtf8().data());
        QFileInfo const file_info(filePath.toLocalFile());
        if (!file_info.exists()) {
            return "";
        }

        return file_info.fileName();
    }

获取文件路径

cpp 复制代码
    Q_INVOKABLE static QString getFilePath(const QUrl &filePath) {
        return filePath.toLocalFile();
    }

获取文件大小

采用windows文件操作方式实现,其实我觉得没必要,用qt的实现更简单

cpp 复制代码
static size_t fileSize(std::string_view path) noexcept {
        HANDLE file_info = CreateFile(charToWchar(path).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
                                      FILE_ATTRIBUTE_NORMAL, nullptr);
        if (file_info == INVALID_HANDLE_VALUE)
            return 0;

        LARGE_INTEGER size;
        if (!GetFileSizeEx(file_info, &size)) {
            CloseHandle(file_info);
            return 0;
        }
        CloseHandle(file_info);
        return static_cast<size_t>(size.QuadPart);
    }
cpp 复制代码
Q_INVOKABLE static QString getFileSize(const QUrl &filePath) {
        return getSize(filePath.toLocalFile());
    }

    Q_INVOKABLE static QString getSize(const QString &filePath) {
        QFileInfo const file_info(filePath);
        if (!file_info.exists() || file_info.isDir())
            return {};

        auto const size = file_info.size();
        return CommonTool::fileSize(static_cast<uint64_t>(size));
    }

这个功能函数说实话,如果是我只会有一个函数实现。

获取app路径

cpp 复制代码
    Q_INVOKABLE static QString getAppPath() {
        return QCoreApplication::applicationDirPath();
    }

生成不重名文件函数

cpp 复制代码
 Q_INVOKABLE static QString getUniqueFileName(const QString &filePath) {
        return CommonTool::getUniqueFileName(filePath.toUtf8().data()).c_str();
    }

检查文件是否存在

cpp 复制代码
static bool fileExists(const std::string_view file_path) noexcept {
    DWORD const attr = GetFileAttributes(charToWchar(file_path).c_str());
    return (attr != INVALID_FILE_ATTRIBUTES);
}

创建不重名文件

cpp 复制代码
static std::string getUniqueFileName(const std::string_view file_path) noexcept {
        spdlog::debug("getUniqueFileName: {}", file_path);
        if (!fileExists(file_path))
            return std::string(file_path);
        std::string base_name = getBaseName(file_path);
        std::string const extension = '.' + getExtention(file_path);
        std::string const dir_path = directory(file_path);
        spdlog::debug("base_name: {}", base_name);

        int count = 1;
        std::string new_name = base_name + extension;

        std::string new_path = dir_path + "/" + new_name;
        spdlog::debug("new_path: {}", new_path);
        bool exists = fileExists(new_path);
        while (exists) {
            new_name = base_name;
            new_name += '(' + std::to_string(count) + ')' + extension;
            new_path = dir_path + "/";
            new_path += new_name;
            spdlog::debug("new_path: {}", new_path);
            count++;
            exists = fileExists(new_path);
        }
        spdlog::debug("getUniqueFileName: {}", dir_path + "/" + new_name);
        return dir_path + "/" + new_name;
    }
cpp 复制代码
   Q_INVOKABLE static QString getUniqueFileName(const QString &filePath) {
        return CommonTool::getUniqueFileName(filePath.toUtf8().data()).c_str();
    }

获取文件名

cpp 复制代码
static std::string getBaseName(std::string_view path) noexcept {
        std::string const path_str(path);
        size_t const pos_slash = path_str.find_last_of("\\/");
        std::string file_name = (pos_slash != std::string::npos) ? path_str.substr(pos_slash + 1) : path_str;

        size_t const pos_dot = file_name.find_last_of('.');
        if (pos_dot != std::string::npos) {
            file_name = file_name.substr(0, pos_dot);
        }
        return file_name;
    }

就是找到/和.之间的文件名返回,采用的是c++的string_view,其实也可以用字符串的find操作或者qt的qfileinfo::basename一样可以实现。

相关推荐
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1235 天前
matlab画图工具
开发语言·matlab
dustcell.5 天前
haproxy七层代理
java·开发语言·前端
norlan_jame5 天前
C-PHY与D-PHY差异
c语言·开发语言
多恩Stone5 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ4022054965 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
遥遥江上月5 天前
Node.js + Stagehand + Python 部署
开发语言·python·node.js
m0_531237175 天前
C语言-数组练习进阶
c语言·开发语言·算法
Railshiqian5 天前
给android源码下的模拟器添加两个后排屏的修改
android·开发语言·javascript
雪人不是菜鸡5 天前
简单工厂模式
开发语言·算法·c#