纯C++操作文件和文件夹的工具类

前言

一般涉及到文件和文件夹的操作的时候,要么使用QtQFile或者QDir类,要么使用别的库。但是当我们的程序不想包含太多太杂的库的时候,对于文件夹的操作就不那么容易了。因此,为解决这个问题,本文创建了一个File类,以及从File类派生出的Dir类,用以对文件和文件夹进行操作。

基本想法

为什么需要从File类派生出Dir类呢?
是因为在linux下,所有东西都可以看成文件,因此文件夹属于一类特殊的文件,故从File类派生出Dir类,以重用File类的一些方法。

特点

  • 纯C++,不包含其他的任何第三方库
  • 使用简单明了

代码

#ifndef FILE_V2_H
#define FILE_V2_H

#if defined (WIN32) || defined (WIN64) || defined (_MSC_VER)
#include <io.h>
#include <direct.h>
#elif defined(_linux) || defined(MINGW)
#include <io.h>
#include <direct.h>
#endif

#include <string>
#include <list>
#include <vector>

/* ****************************************************************************************************
** Class Name: File
** ----------------------------------------------------------------------------------------------------
** Author: geocat & Little bottle
** ----------------------------------------------------------------------------------------------------
** CreateTime:
** ----------------------------------------------------------------------------------------------------
** LastEditTime:
** ----------------------------------------------------------------------------------------------------
** Brief:
**      这是文件操作类
**      包含文件的创建、复制、遍历文件夹等操作
**
**
** ***************************************************************************************************/

/** 该函数将给定的路径中的"\\" 替换成 "/",同时将路径尾后的"/"去掉
 */
void sepReplace(std::string& sPath);

/** 给定一个路径,判断该路径是文件还是文件夹
  * 返回值为1,则为文件,返回2则为文件夹,返回0则为错误,可能改路径不是常规文件/文件夹路径
  */
int isFileOrDir(const std::string& sPath);

/**
 * @brief
 * 从给定的文件,得到其多级子目录,按照其对应顺序存储到vSubDirs中
 * 如:str = "\\DirA\\DirB\\DirC\\FileA"
 * 则转换后的vSubDirs为:[
 *                     DirA,
 *                     DirA/DirB,
 *                     DirA/DirB/DirC,
 *                     DirA/DirB/DirC/FileA
 *                    ]
 * @param str
 * @param vSubDirs
 */
void getMultiLayerDirFromStr(const std::string& str, std::vector<std::string>& vSubDirs);

/**
 * @brief 字符串分割函数,按照给定的分割字符cSep进行分割。分割结果存储在vTokenRes中
 * @param str
 * @param cSep
 * @param vTokenRes
 */
void strToken(const std::string& str, const char cSep, std::vector<std::string>& vTokenRes);

class Dir;

class File
{
public:
    File(const std::string& sFilePath = "");
    virtual ~File();

    void setFilePath(const std::string& sFilePath);

    std::string fileName();
    const std::string& filePath();

    bool isFile();
    bool isDir();

    // 返回当前文件所在目录的对象
    Dir parentDir();

    // 当前文件夹下创建文件
    bool touch(const std::string& sFileName);
    // 指定文件夹,在其下创建新文件
    static bool touch(const std::string& sTarDirName, const std::string& sNewFileName);

    // 将当前文件复制到目标文件夹下
    virtual bool copy(const std::string& sTarDirPath);
    // 指定文件夹,将指定文件拷贝到指定文件夹下
    static bool copy(const std::string& sTarDirName, const std::string& sFilePath);

protected:
    std::string m_sFilePath;
    int m_iIsFileOrDir;
};

typedef std::list<File*> FileList;

class Dir: public File
{
public:
    Dir(const std::string& sDirPath = "");
    ~Dir();

    bool mkdir(const std::string& sNewDirName);
    static bool mkdir(const std::string& sTarDirPath, const std::string& sNewDirName);


    // 遍历当前文件夹下的所有文件
    // 如果bDeepTraverse为FALSE,则只遍历当前目录
    // 如果bDeepTraverse为TRUE, 则遍历当前目录的所有子目录及其文件
    const FileList& entry(bool bDeepTraverse = false);
    // 静态函数
    static FileList entry_static(const std::string& sDirPath, bool bDeepTraverse = false);      // ???

    // 重载函数,将当前文件夹复制到目标文件夹下
    bool copy(const std::string &sTarDirPath) override;
    // 将一个给定的文件夹,复制到目标文件夹,不在目标文件夹下创建当前文件夹,只是把当前文件夹里的所有内容复制到目标文件夹下。
    static bool copy(const std::string &sSrcDirPath, const std::string &sTarDirPath);

protected:
    static void listFiles(const std::string& sDirPath, FileList& list);
    static void listFiles_Deep(const std::string& sDirPath, FileList& list);

protected:
    FileList m_lstFileList;
};

// 获取给定的文件相对于给定的文件夹的相对路径
// 文件需要存在于文件夹中,如果文件不存在与文件夹,返回空字符串
std::string getRelativePath(File& file, Dir& dir);

#endif // FILE_V2_H

以上是头文件的一些方法的定义,接下来就是具体实现了。上代码:

#include "File.h"
#include <fstream>

void sepReplace(std::string &sPath)
{
    int iPos = 0;
    while (sPath.find('\\') != sPath.npos) {
        iPos = sPath.find('\\', iPos);
        sPath = sPath.replace(iPos, 1, "/");
    }

    if(sPath.back() == '/')
        sPath.pop_back();
}

int isFileOrDir(const std::string &sPath)
{
    intptr_t handle;
    _finddata_t findData;

    handle = _findfirst(sPath.c_str(), &findData);
    if(findData.attrib & _A_SUBDIR)
        return 2;
    else
        return 1;

    _findclose(handle);
}

void getMultiLayerDirFromStr(const std::string &str, std::vector<std::string> &vSubDirs)
{
    std::string sOriStrCp = str;
    // 将原始字符串的"\\"替换成"/"
    sepReplace(sOriStrCp);
    // 将字符串进行分割
    std::vector<std::string> vTokenRes;
    strToken(sOriStrCp, '/', vTokenRes);
    // 将分割后的结果,按照逐步累加的方式,存储到vSubDirs中
    vSubDirs.push_back(vTokenRes.front());
    for(int i = 1; i < (int)vTokenRes.size(); i++)
    {
        vSubDirs.push_back(vSubDirs[i - 1] + "/" + vTokenRes[i]);
    }
}

void strToken(const std::string& str, const char cSep, std::vector<std::string>& vTokenRes)
{
    int iPos = 0;
    while (str.find(cSep, iPos) != str.npos) {
        vTokenRes.push_back(str.substr(iPos, str.find(cSep, iPos)));
        iPos = str.find(cSep, iPos) + 1;
    }
    vTokenRes.push_back(str.substr(iPos));
}

File::File(const std::string& sFilePath):
    m_sFilePath(sFilePath)
{
    m_iIsFileOrDir = isFileOrDir(m_sFilePath);
}

File::~File()
{

}

void File::setFilePath(const std::string &sFilePath)
{
    this->m_sFilePath = sFilePath;
    sepReplace(m_sFilePath);
}

std::string File::fileName()
{
    return m_sFilePath.substr(m_sFilePath.find_last_of('/') + 1);
}

const std::string& File::filePath()
{
    return m_sFilePath;
}

bool File::isFile()
{
    return m_iIsFileOrDir == 1;
}

bool File::isDir()
{
    return m_iIsFileOrDir == 2;
}

Dir File::parentDir()
{
    Dir pD;
    pD.setFilePath(this->m_sFilePath.substr(0, m_sFilePath.find_last_of('/')));

    return pD;
}

bool File::touch(const std::string &sFileName)
{
    std::string sDirPath = this->parentDir().filePath();

    std::string sNewFilePath;
    sNewFilePath = sDirPath + std::string("/") + std::string(sFileName);

    /* _access函数说明:(参考链接:https://blog.csdn.net/monk1992/article/details/81906013)
     * 头文件:<io.h>
     * 函数原型:int _access(const char *pathname, int mode);
     * 参数:pathname 为文件路径或目录路径 mode 为访问权限(在不同系统中可能用不能的宏定义重新定义)
     * 返回值:如果文件具有指定的访问权限,则函数返回0;如果文件不存在或者不能访问指定的权限,则返回-1.
     * 备注:当pathname为文件时,_access函数判断文件是否存在,并判断文件是否可以用mode值指定的模式进行访问。当pathname为目录时,_access只判断指定目录是否存在,在Windows NT和Windows 2000中,所有的目录都只有读写权限。
     * mode的值和含义如下所示:
     * 00——只检查文件是否存在
     * 02——写权限
     * 04——读权限
     * 06——读写权限
    */
    if(0 != _access(sDirPath.c_str(), 2))
    {
        printf("***ERROR***: Dest dir has no writing access.\n");
        return false;
    }

    std::ofstream os(sNewFilePath, std::ios::out);
    if(os.is_open())
    {
        os.close();
        return true;
    }
    else
    {
        os.close();
        return false;
    }
}

bool File::touch(const std::string &sTarDirName, const std::string &sNewFileName)
{
    std::string sParent = sTarDirName;
    sepReplace(sParent);

    if(0 != _access(sParent.c_str(), 2))
    {
        printf("***ERROR***: Dest dir has no writing access.\n");
        return false;
    }

    std::string sNewFilePath = sParent;

    // 如果sNewFileName是包含多级目录的文件,如:DirA\\DirB\\DirB\\FileA.txt;
    // 则需要将该文件路径拆分开,分别创建多级目录,再创建文件
//    if(sNewFileName.find('/') != sNewFileName.npos || sNewFileName.find('\\') != sNewFileName.npos)
//    {
//        std::vector<std::string> sSubDirs;
//        getMultiLayerDirFromStr(sNewFileName, sSubDirs);
//        for(int i = 0; i < (int)sSubDirs.size() - 1; i++)
//        {
//            Dir::mkdir(sTarDirName, sSubDirs[i]);
//        }
//    }

    sNewFilePath.append("/").append(sNewFileName);

    std::ofstream os(sNewFilePath, std::ios::out);
    if(os.is_open())
    {
        os.close();
        return true;
    }
    else
    {
        os.close();
        return false;
    }
}

bool File::copy(const std::string &sTarDirPath)
{
    if(0 != _access(sTarDirPath.c_str(), 2))
    {
        printf("***ERROR***: Dest dir has no writing access.\n");
        return false;
    }

    /* 将本文件复制到pTarDirPath下 */
    // 1. 读文件,二进制方式打开
    std::ifstream inFile(m_sFilePath, std::ios::in | std::ios::binary);
    if(! inFile.is_open())
    {
        printf("***ERROR***: File open failure.\n");
        inFile.close();
        return false;
    }

    // 2. 在目标文件夹下创建新当前同名文件
        // 可以做个判断该文件是否存在
    bool touchRes = File::touch(sTarDirPath, this->fileName().c_str());
    if(touchRes == false)
    {
        printf("***ERROR***: New file created to target dir failed.\n");
        inFile.close();
        return false;
    }

    std::string sNewFilePath = std::string(sTarDirPath) + "/" + this->fileName();

    // 3. 打开创建的该新文件,并将数据复制到该文件中
    std::ofstream outFile(sNewFilePath, std::ios::out | std::ios::binary);
    if(! outFile.is_open())
    {
        printf("***ERROR***: Open copied new file failed.\n");
        inFile.close();
        outFile.close();
        return false;
    }

    outFile << inFile.rdbuf();  // 这句话网上也是这样用的,说速度很快

    inFile.close();
    outFile.close();

    return true;
}

bool File::copy(const std::string &sTarDirName, const std::string &sFilePath)
{
    if(0 != _access(sTarDirName.c_str(), 2))
    {
        printf("***ERROR***: Dest dir has no writing access.\n");
        return false;
    }

    std::ifstream inFile(sFilePath, std::ios::in | std::ios::binary);
    if(! inFile.is_open())
    {
        printf("***ERROR***: Open file failure.\n");
        inFile.close();
        return false;
    }

    // 在目标文件夹下创建新文件
    std::string sTarDir = sTarDirName;
    sepReplace(sTarDir);
    File oriFile(sFilePath);
    bool touchRes = File::touch(sTarDir, oriFile.fileName());
    if(touchRes == false)
    {
        printf("***ERROR***: Touch new file failure.\n");
        inFile.close();
        return false;
    }

    std::string sNewFilePath = sTarDir + "/" + oriFile.fileName();

    // 3. 打开创建的该新文件,并将数据复制到该文件中
    std::ofstream outFile(sNewFilePath, std::ios::out | std::ios::binary);
    if(! outFile.is_open())
    {
        printf("***ERROR***: Open copied new file failed.\n");
        inFile.close();
        outFile.close();
        return false;
    }

    outFile << inFile.rdbuf();  // 这句话网上也是这样用的,说速度很快

    inFile.close();
    outFile.close();

    return true;
}

Dir::Dir(const std::string& sDirPath)
{
    m_sFilePath = sDirPath;
    sepReplace(m_sFilePath);

    m_iIsFileOrDir = isFileOrDir(m_sFilePath);
}

Dir::~Dir()
{
    while (! m_lstFileList.empty()) {
        auto file = m_lstFileList.front();
        if(file != nullptr)
        {
            delete file;
            m_lstFileList.pop_front();
        }
    }
}

bool Dir::mkdir(const std::string &sNewDirName)
{
    if(0 != _access(m_sFilePath.c_str(), 2))
    {
        printf("***ERROR***: Curent dir has no writing access.\n");
        return false;
    }

    // 如果sNewDirName是多级子目录组成的,则对其进行拆分处理
    std::vector<std::string> vSubDirs;
    getMultiLayerDirFromStr(sNewDirName, vSubDirs);
    for(int i = 0; i < (int)vSubDirs.size(); i++)
    {
        std::string sSubDirPath = sNewDirName + vSubDirs[i];
        _mkdir(sSubDirPath.c_str());
    }

//    std::string sNewDirPath;
//    sNewDirPath = m_sFilePath + std::string("/") + sNewDirName;
//    int iMkdirRes = _mkdir(sNewDirPath.c_str());

    return true;
}

bool Dir::mkdir(const std::string &sTarDirPath, const std::string &sNewDirName)
{
    std::string sParentDirPath = sTarDirPath;
    sepReplace(sParentDirPath);
    if(0 != _access(sParentDirPath.c_str(), 2))
    {
        printf("***ERROR***: Dest dir has no writing access.\n");
        return false;
    }

    // 如果sNewDirName是多级子目录组成的,则对其进行拆分处理
    std::vector<std::string> vSubDirs;
    getMultiLayerDirFromStr(sNewDirName, vSubDirs);
    for(int i = 0; i < (int)vSubDirs.size(); i++)
    {
        std::string sSubDirPath = sTarDirPath + "/" + vSubDirs[i];
        _mkdir(sSubDirPath.c_str());
    }

//    std::string sNewDirPath;
//    sNewDirPath = sParentDirPath + std::string("/") + sNewDirName;
//    int iMkdirRes = _mkdir(sNewDirPath.c_str());

    return true;
}

const FileList& Dir::entry(bool bDeepTraverse)
{
    if(bDeepTraverse == false)
        listFiles(m_sFilePath, m_lstFileList);
    else
        listFiles_Deep(m_sFilePath, m_lstFileList);
    return m_lstFileList;
}

FileList Dir::entry_static(const std::string& sDirPath, bool bDeepTraverse)
{
    FileList list;
    if(bDeepTraverse == false)
        listFiles(sDirPath, list);
    else
        listFiles_Deep(sDirPath, list);
    return list;
}

bool Dir::copy(const std::string &sTarDirPath)
{
    // 判断目标文件夹是否有写权限
    if(0 != _access(sTarDirPath.c_str(), 2))
    {
        printf("***ERROR***: Dest dir path has no writing access.\n");
        return false;
    }
    auto curFiles = this->entry(true);
    for(auto file: curFiles)
    {
        if(file->isFile())
        {
            // 将当前文件的文件路径减去当前文件夹的路径,得到当前文件相对当前文件夹的相对路径
            std::string sRelPath = getRelativePath(*file, *this);
            // 相对路径的前缀
            std::string sPrefix;
            if(sRelPath.find('/') != sRelPath.npos)
                sPrefix = sRelPath.substr(0, sRelPath.find_last_of('/'));
            else
                sPrefix = "";
            // 在目标目录下创建相对路径的前缀
            if(sPrefix == "")
            {
                File::copy(sTarDirPath, file->filePath());
            }
            else
            {
                Dir::mkdir(sTarDirPath, sPrefix);
                File::copy(sTarDirPath + "/" + sPrefix, file->filePath()); // ??????????????????????????  TODO
            }
        }
    }

    // 内存回收 —— curFiles是在entry_static中创建的,因此需要手动回收
    while (! curFiles.empty()) {
        auto file = curFiles.front();
        if(file != nullptr)
        {
            delete file;
            curFiles.pop_front();
        }
    }
    return true;
}

bool Dir::copy(const std::string &sSrcDirPath, const std::string &sTarDirPath)
{
    // 判断对目标文件夹是否有写权限
    if(0 != _access(sTarDirPath.c_str(), 2))
    {
        printf("***ERROR***: Dest dir path has no writing access.\n");
        return false;
    }

    Dir srcDir(sSrcDirPath);

    // 遍历当前文件夹,得到所有的文件
    auto curFiles = Dir::entry_static(sSrcDirPath, true);
    for(auto file: curFiles)
    {
        if(file->isFile())
        {
            // 将当前文件的文件路径减去当前文件夹的路径,得到当前文件相对当前文件夹的相对路径
            std::string sRelPath = getRelativePath(*file, srcDir);
            // 相对路径的前缀
            std::string sPrefix;
            if(sRelPath.find('/') != sRelPath.npos)
                sPrefix = sRelPath.substr(0, sRelPath.find_last_of('/'));
            else
                sPrefix = "";
            // 在目标目录下创建相对路径的前缀
            if(sPrefix == "")
            {
                File::copy(sTarDirPath, file->filePath());
            }
            else
            {
                Dir::mkdir(sTarDirPath, sPrefix);
                File::copy(sTarDirPath + "/" + sPrefix, file->filePath()); // ??????????????????????????  TODO
            }
        }
    }

    // 内存回收 —— curFiles是在entry_static中创建的,因此需要手动回收
    while (! curFiles.empty()) {
        auto file = curFiles.front();
        if(file != nullptr)
        {
            delete file;
            curFiles.pop_front();
        }
    }
    return true;
}

void Dir::listFiles(const std::string& sDirPath, FileList& list)
{
    intptr_t handle;
    _finddata_t findData;

    std::string sDir = sDirPath;
    sepReplace(sDir);

    std::string sAddWildcardCharacter = sDir + "/*.*";   // 必须加上这种通配符,否则只循环一次
//    std::string sAddWildcardCharacter = m_sFilePath + "/";    // 这种目录后加斜杠的不行,会find失败

    handle = _findfirst(sAddWildcardCharacter.c_str(), &findData);
    if(-1 == handle)
    {
        printf("***ERROR***: Find first file failure.\n");
        return;
    }

    do {
        if(findData.attrib & _A_SUBDIR)
        {
            if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0)
                continue;

            Dir* pDir = new Dir(sDir + "/" + findData.name);
            list.push_back(pDir);
        }
        else
        {
            File* pFile = new File(sDir + "/" + findData.name);
            list.push_back(pFile);
        }
    } while (_findnext(handle, &findData) == 0);

    _findclose(handle);
}

void Dir::listFiles_Deep(const std::string &sDirPath, FileList& list)
{
    intptr_t handle;
    _finddata_t findData;

    std::string sDir = sDirPath;
    sepReplace(sDir);

    std::string sAddWildcardCharacter = sDir + "/*.*";   // 必须加上这种通配符,否则只循环一次
//    std::string sAddWildcardCharacter = m_sFilePath + "/";    // 这种目录后加斜杠的不行,会find失败

    handle = _findfirst(sAddWildcardCharacter.c_str(), &findData);
    if(-1 == handle)
    {
        printf("***ERROR***: Find first file failure.\n");
        return;
    }

    do {
        if(findData.attrib & _A_SUBDIR)
        {
            if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0)
                continue;

            Dir* pDir = new Dir(sDir + "/" + findData.name);
            list.push_back(pDir);

            if(pDir->fileName().back() == '.')
                continue;
            listFiles_Deep(sDir + "/" + findData.name, list);
        }
        else
        {
            File* pFile = new File(sDir + "/" + findData.name);
            list.push_back(pFile);
        }
    } while (_findnext(handle, &findData) == 0);

    _findclose(handle);
}

std::string getRelativePath(File &file, Dir &dir)
{
    std::string sFilePath = file.filePath();
    std::string sDirPath = dir.filePath();

    if(sFilePath.find(sDirPath) == std::string::npos)
        return "";

    return sFilePath.substr(sDirPath.length() + 1);
}

代码说明

没什么好说明,这两个文件,在要使用的时候直接包含到你的工程中就行。每一个函数的用法都在上面。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
DirectX修复工具(DirectX Repair)是一款系统级工具软件,简便易用。本程序为绿色版,无需安装,可直接运行。 本程序的主要功能是检测当前系统的DirectX状态,如果发现异常则进行修复。程序主要针对0xc000007b问题设计,可以完美修复该问题。本程序中包含了最新版的DirectX redist(Jun2010),并且全部DX文件都有Microsoft的数字签名,安全放心。 本程序为了应对一般电脑用户的使用,采用了傻瓜式一键设计,只要点击主界面上的“检测并修复”按钮,程序就会自动完成校验、检测、下载、修复以及注册的全部功能,无需用户的介入,大大降低了使用难度。 本程序适用于多个操作系统,如Windows XP(需先安装.NET 2.0,详情请参阅“致Windows XP用户.txt”文件)、Windows Vista、Windows 7、Windows 8、Windows 8.1、Windows 8.1 Update、Windows 10,同时兼容32位操作系统和64位操作系统。本程序会根据系统的不同,自动调整任务模式,无需用户进行设置。 本程序的V3.8版分为标准版、增强版以及在线修复版。所有版本都支持修复DirectX的功能,而增强版则额外支持修复c++的功能。在线修复版功能与标准版相同,但其所需的数据包需要在修复时自动下载。各个版本之间,主程序完全相同,只是其配套使用的数据包不同。因此,标准版和在线修复版可以通过补全扩展包的形式成为增强版。本程序自V3.5版起,自带扩展功能。只要在主界面的“工具”菜单下打开“选项”对话框,找到“扩展”标签,点击其中的“开始扩展”按钮即可。扩展过程需要Internet连接,扩展成功后新的数据包可自动生效。扩展用时根据网络速度不同而不同,最快仅需数秒,最慢需要数分钟,烦请耐心等待。 本程序自V2.0版起采用全新的底层程序架构,使用了异步多线程编程技术,使得检测、下载、修复单独进行,互不干扰,快速如飞。新程序更改了自我校验方式,因此使用新版本的程序时不会再出现自我校验失败的错误;但并非取消自我校验,因此程序安全性与之前版本相同,并未降低。 程序有自动更新c++功能。由于绝大多数软件运行时需要c++的支持,并且c++的异常也会导致0xc000007b错误,因此程序在检测修复的同时,也会根据需要更新系统中的c++组件。自V3.2版本开始使用了全新的c++扩展包,可以大幅提高工业软件修复成功的概率。修复c++的功能仅限于增强版,标准版及在线修复版在系统c++异常时(非丢失时)会提示用户使用增强版进行修复。除常规修复外,新版程序还支持C++强力修复功能。当常规修复无效时,可以到本程序的选项界面内开启强力修复功能,可大幅提高修复成功率。请注意,此功能为试验性功能,请仅在常规修复无效时再使用。 程序有两种窗口样式。正常模式即默认样式,适合绝大多数用户使用。另有一种简约模式,此时窗口将只显示最基本的内容,修复会自动进行,修复完成10秒钟后会自动退出。该窗口样式可以使修复工作变得更加简单快速,同时方便其他软件、游戏将本程序内嵌,即可进行无需人工参与的快速修复。开启简约模式的方法是:打开程序所在目录下的“Settings.ini”文件(如果没有可以自己创建),将其中的“FormStyle”一项的值改为“Simple”并保存即可。 新版程序支持命令行运行模式。在命令行中调用本程序,可以在路径后直接添加命令进行相应的设置。常见的命令有7类,分别是设置语言的命令、设置窗口模式的命令,设置安全级别的命令、开启强力修复的命令、设置c++修复模式的命令、控制DirectDraw的命令、显示版权信息的命令。具体命令名称可以通过“/help”或“/?”进行查询。 程序有高级筛选功能,开启该功能后用户可以自主选择要修复的文件,避免了其他不必要的修复工作。同时,也支持通过文件进行辅助筛选,只要在程序目录下建立“Filter.dat”文件,其中的每一行写一个需要修复文件的序号即可。该功能仅针对高级用户使用,并且必须在正常窗口模式下才有效(简约模式时无效)。 本程序有自动记录日志功能,可以记录每一次检测修复结果,方便在出现问题时,及时分析和查找原因,以便找到解决办法。 程序的“选项”对话框中包含了6项高级功能。点击其中的“注册系统文件夹中所有dll文件”按钮可以自动注册系统文件夹下的所有dll文件。该项功能不仅能修复DirectX的问题,还可以修复系统中很多其他由于dll未注册而产生的问题,颇为实用。点击该按钮旁边的小箭头,还可以注册任意指定文件夹下的dll文件,方便用户对绿色版、硬盘版的程序组件进行注册。点击第二个按钮可以为dll文件的右键菜单添加“注册”和“卸载”项,方便对单独的dll文件进行注册。请注意,并不是所有的dll文件都可以通过这种方式注册。点击“扩展”选项卡可以将任意版本的程序扩展成增强版。点击“DirectX版本”选项卡,可以自行修改系统中DirectX的版本信息。点击“DirectX加速”选项卡可以控制系统中DirectX加速的开启与关闭。点击“实验室”选项卡可以开启实验功能:C++强力修复功能,通过全新的代码设计,彻底改善对于顽固异常文件处理,极大提高修复成功率。API Sets强力修复功能,参照了DirectX文件的精细修复方式,极大地改善了修复失败的情况。修复失败时启用调试模式功能,可以在出现问题时分析错误原因。 新版程序集成了用户反馈程序,可以在用户允许的前提下发送检测修复结果。用户也可以在出现问题时通过反馈程序和软件作者进行交流,共同查找问题。反馈是完全自愿和匿名(如果不填写E-mail地址)的。 本程序的通用版基于Microsoft .NET Framework 2.0开发,对于Windows 2000、Windows XP、Windows 2003的用户需要首先安装.NET Framework 2.0或更高版本方可运行本程序。有关下载和安装的详细信息请参阅“致Windows XP用户.txt”文件。对于Windows Vista、Windows 7及后续用户,可以直接运行本程序。
### 回答1: C dump文件生成类是一个用于生成dump文件的类。dump文件也被称为崩溃转储文件,它记录了程序在崩溃或异常情况下的内存状态和相关信息,帮助开发者进行故障排查和分析。 这个类的主要功能是在发生异常或程序崩溃时,通过捕获异常或信号,将当前运行环境的内存状态保存到文件中。它可以捕获一些常见的崩溃或异常类型,如访问非法内存、除零错误等,也可以处理自定义异常。 生成dump文件的过程通常包括以下几个步骤: 首先,类需要设置一个回调函数或信号处理函数,用于在程序发生崩溃或异常时进行处理。这个函数会在捕获到异常或信号时被调用,然后通过调用系统相关的API获取当前的内存状态,并写入到文件中。生成的dump文件通常是二进制格式的,可以包含整个程序虚拟内存的内容。 其次,类需要提供一些方法或接口,供开发者在需要时手动触发生成dump文件操作。这可以通过类的方法调用或特定的命令来实现。 最后,生成的dump文件需要保存到指定的位置,通常是在程序的运行目录或特定的文件夹中。开发者可以根据需要设置文件的命名规则,以便更好地区分和管理不同版本或不同场景下的dump文件。 总之,C dump文件生成类是一个重要的调试工具,它可以帮助开发者快速定位并解决程序崩溃或异常问题。它的实现需要深入了解操作系统和编程语言的相关知识,以及对异常处理和内存管理的理解。 ### 回答2: c dump 文件生成类是一个用于生成C语言代码的工具类。它的主要功能是将已经生成的C语言代码转化为dump文件,以便后续的调试和分析。 该类提供了一系列的方法,用于生成不同类型的dump文件。其中包括生成函数调用栈信息的dump文件、生成全局变量的dump文件、生成局部变量的dump文件等等。用户可以根据自己的需求选择相应的方法来生成相应类型的dump文件。 生成dump文件的过程主要包括以下几个步骤: 首先,该类会将待生成的C语言代码读入内存,并且解析该代码,提取出需要的信息,例如函数调用栈、全局变量、局部变量等等。 然后,生成类会根据解析到的信息,按照一定的格式将这些信息写入到dump文件中。这些信息可以是文本格式,也可以是二进制格式,根据用户的设置而定。 最后,生成类还会提供一些其他的功能,例如生成dump文件的摘要信息、添加自定义的调试信息等等,以便用户更好地理解和分析dump文件。 总之,c dump文件生成类是一个非常实用的工具类,它可以帮助开发者生成各种类型的dump文件,方便后续的调试和分析工作。无论是在软件开发过程中还是在软件维护过程中,它都是一个非常有用的工具。 ### 回答3: C dump文件生成类是一种能够生成C程序的内存转储文件(dump文件)的类。在C语言中,dump文件是一种二进制文件,它记录了程序在某个特定时刻的内存状态。通过生成dump文件,可以方便地保存和恢复程序的内存状态,以便进行调试和分析。 C dump文件生成类通常提供以下功能: 1. 内存转储:该类可以将程序的内存状态保存到dump文件中。通过遍历内存中的各个变量和数据结构,将其以二进制形式写入文件。这样,就可以在程序崩溃或出现错误时,通过读取dump文件还原内存状态,进行问题分析。 2. 文件格式:该类会定义一套特定的文件格式,用于指定dump文件中各个内存区域的结构。这样,在读取dump文件时,可以按照这个文件格式来解析文件,并恢复内存状态。 3. 文件操作:该类提供了一系列文件操作的方法,包括打开、关闭、读取和写入。通过这些方法,可以方便地对dump文件进行操作,例如打开已有的dump文件、新建一个dump文件或者向已有的dump文件追加数据。 4. 错误处理:该类会包含错误处理的机制,以处理文件操作失败或其他原因导致的错误。例如,如果打开dump文件失败,则会返回相应的错误代码或者抛出异常,以便进行相应的错误处理。 总之,C dump文件生成类是一种用于生成C程序内存转储文件的类。它提供了将程序内存状态保存到dump文件的功能,并包括文件格式定义、文件操作方法等。通过使用这种类,可以方便地进行程序的调试和分析,快速定位和解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

geocat

球球大佬们赏赐点吃喝!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值