侧边栏壁纸
  • 累计撰写 278 篇文章
  • 累计创建 3 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

【MFC】 MFC文件操作和注册表操作

xuanxuan
2022-01-09 / 0 评论 / 0 点赞 / 3 阅读 / 11379 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2024-02-14,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

MFC文件和注册表的操作

日志、操作配置文件、ini文件、注册表、音视频的文件存储。

Linux下一切皆文件。

C/C++文件操作

常量指针和指针常量

const char p == char const p 常量指针,表示指向的内容为常量,指针的指向可以修改,指针指向的内容不能修改。

char* const p 指针常量,表示地址是常量,指向不能改变,指向的内容可以改变。

C语言文件操作

文件打开的模式

image-20220108164525100

示例:

//写文件
void CMFCFileView::OnFileWrite()
{
    FILE* pFile = NULL;
    //打开文件
    errno_t err = _wfopen_s(&pFile,_T("1.txt"),_T("w"));
    if (!err)
    {

    }
    else
    {
        TRACE("Open Fail ErrorCode = %d",GetLastError());
        return;
    }
    fwrite(_T("ohguradianbyebye"), 2, wcslen(_T("ohguradianbyebye"))+1, pFile); //wcslen求宽字符串的长度
    fclose(pFile);
}

//读文件
void CMFCFileView::OnFileRead()
{
    FILE* pFile = NULL;
    //打开文件
    errno_t err = _wfopen_s(&pFile, _T("1.txt"), _T("r"));
    if (!err)
    {

    }
    else
    {
        TRACE("Open Fail ErrorCode = %d", GetLastError());
        return;
    }
    fseek(pFile, 0, SEEK_END);//偏移到结尾位置
    int len = ftell(pFile);//得到文件指针的当前位置,也就是文件长度。
    WCHAR *pBuf=new WCHAR[len+1];
    fseek(pFile,0,SEEK_SET);//文件指针回到开头位置
    //等同于rewind(pFile);
    fread(pBuf,2,len,pFile);//这里是宽字节所以是2
    pBuf[len] = 0;//确保数组最后一个元素为'\0'
    MessageBox(pBuf);
    fclose(pFile);
}

C++文件操作

ofstream类

image-20220108181527795

//写文件
void CMFCFileView::OnFileWrite()
{
    ofstream ofs("2.txt");
    ofs.write("doraemon",strlen("droaemon"));
    ofs. close();
}

//读文件
void CMFCFileView::OnFileRead()
{
    ifstream ifs("2.txt");
    char pBuf[100] = { 0 };
    ifs.read(pBuf,100);
    USES_CONVERSION;
    CString strBuf = A2W(pBuf);
    MessageBox(strBuf);
    ifs.close();
}

Win32 API/MFC文件操作

Win32 API文件操作

HANDLE CreateFileA(
  //创建或打开的对象的名称
  [in]           LPCSTR                lpFileName,
  //访问方式,读、读写,写、查询
  [in]           DWORD                 dwDesiredAccess,
  //共享方式
  [in]           DWORD                 dwShareMode,
     //NULL不能被子进程继承 
  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    //如何创建文件
  [in]           DWORD                dwCreationDisposition,
    //设置文件的属性和标志
  [in]           DWORD                 dwFlagsAndAttributes,
    //NULL
  [in, optional] HANDLE                hTemplateFile
);
WriteFile(
    _In_ HANDLE hFile,
    _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
    //要写入的字节数
    _In_ DWORD nNumberOfBytesToWrite,
    //用来接收实际写入到文件的字节数
    _Out_opt_ LPDWORD lpNumberOfBytesWritten,
    _Inout_opt_ LPOVERLAPPED lpOverlapped
    );

示例:

//写文件
void CMFCFileView::OnFileWrite()
{
    HANDLE  hFile;
    hFile = CreateFile(_T("3.txt"),GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        TRACE("%d", GetLastError());
        return;
    }
    DWORD dwwrites;
    WriteFile(hFile,"Doraemon",strlen("Doraemon"),&dwwrites,NULL);
    CloseHandle(hFile);
}

//读文件
void CMFCFileView::OnFileRead()
{
    HANDLE hFile;
    hFile = CreateFile(_T("3.txt"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    char pBuf[100] = { 0 };
    DWORD dwreads;
    ReadFile(hFile,pBuf,100,&dwreads,NULL);
    USES_CONVERSION;
    CString strBuf = A2W(pBuf);
    MessageBox(strBuf);
    CloseHandle(hFile);
}

MFC文件操作

示例:

//写文件
void CMFCFileView::OnFileWrite()
{
    CFile file(L"4.txt",CFile::modeCreate | CFile::modeWrite);
    file.Write("doraemon",strlen("doraemon"));
    file.Close();
}

//读文件
void CMFCFileView::OnFileRead()
{
    CFile file(L"4.txt",CFile::modeRead);
    char* pBuf;
    DWORD dwFileLen = file.GetLength();
    pBuf = new char[dwFileLen + 1];
    pBuf[dwFileLen] = 0;
    file.Read(pBuf, dwFileLen);
    USES_CONVERSION;
    CString strBuf = A2W(pBuf);
    MessageBox(strBuf);
    file.Close();
}

CFileDialog(
    //TRUE构建一个打开的对话框,FLASE构建一个保存对话框
    BOOL bOpenFileDialog,
    //指定默认的文件扩展名
    LPCTSTR lpszDefExt = NULL,
    //初始化文件名NULL默认没有初始文件名
    LPCTSTR lpszFileName = NULL,
    DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
    //用来指定一个或一组文件的过滤器
    LPCTSTR lpszFilter = NULL,
    //用来指定文件对话框的父窗口或拥有窗口
    CWnd* pParentWnd = NULL,
    DWORD dwSize = 0,
    BOOL bVistaStyle = TRUE);

例如:创建一个默认保存对话框

CFileDialog fileDlg(FALSE);
    fileDlg.DoModal();

文件夹方式保存读取文件

//写文件
void CMFCFileView::OnFileWrite()
{
    CFileDialog fileDlg(FALSE);
    fileDlg.m_ofn.lpstrTitle = L"doraemon";
    fileDlg.m_ofn.lpstrFilter = _T("Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0");
    fileDlg.m_ofn.lpstrDefExt = L"txt";
    if (fileDlg.DoModal() == IDOK)
    {
        CFile file(fileDlg.GetFileName(), CFile::modeCreate | CFile::modeWrite);
        USES_CONVERSION;
        char* szBuf = T2A(fileDlg.GetFileName());
        TRACE("fileDlg.GetFileName()= %s", szBuf);
        file.Write("ZYXXX", strlen("ZYXXX"));
        file.Close();
    }

}

//读文件
void CMFCFileView::OnFileRead()
{
    CFileDialog fileDlg(TRUE);
    fileDlg.m_ofn.lpstrTitle = L"doraemon";
    fileDlg.m_ofn.lpstrFilter = _T("Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0");
    if (fileDlg.DoModal() == IDOK)
    {
        CFile file(fileDlg.GetFileName(), CFile::modeRead);
        char* pBuf;
        DWORD dwFileLen = file.GetLength();
        pBuf = new char[dwFileLen + 1];
        pBuf[dwFileLen] = 0;
        file.Read(pBuf, dwFileLen);
        file.Close();
        USES_CONVERSION;
        CString strBuf = A2W(pBuf );
        MessageBox(strBuf);
    }
}

image-20220109101517226

配置文件的访问与读写

示例:

//写配置文件
void CMFCFileView::OnWirteConfig()
{
    //获取当前路径
    WCHAR strPath[MAX_PATH] = { 0 };
    GetCurrentDirectoryW(MAX_PATH,strPath);
    CString strFilePath;
    strFilePath.Format(L"%ls//Test.ini",strPath);
    WritePrivateProfileStringW(L"metadata",L"title",L"搜狗双拼",strFilePath);
    WritePrivateProfileStringW(L"声母",L"ch",L"I",strFilePath);
    WritePrivateProfileStringW(L"声母",L"sh",L"U",strFilePath);
}

//读配置文件
void CMFCFileView::OnReadConfig()
{
    WCHAR strPath[MAX_PATH] = { 0 };
    WCHAR strTitle[MAX_PATH] = { 0 };
    WCHAR strCh[MAX_PATH] = { 0 };
    WCHAR strSh[MAX_PATH] = { 0 };
    GetCurrentDirectoryW(MAX_PATH, strPath);
    CString strFilePath;
    strFilePath.Format(L"%ls//Test.ini", strPath);
    DWORD dwNum1 = GetPrivateProfileStringW(L"metadata",L"title",NULL,strTitle,MAX_PATH,strFilePath);
    DWORD dwNum2 = GetPrivateProfileStringW(L"声母",L"ch",NULL,strTitle,MAX_PATH,strFilePath);
    DWORD dwNum3 = GetPrivateProfileStringW(L"声母",L"sh",NULL,strTitle,MAX_PATH,strFilePath);
    USES_CONVERSION;
    char* szTitle = W2A(strTitle);
    char*  szSh = W2A(strSh);
    char* szCh = W2A(strCh);
    TRACE("strTitle = %s . strCh = %s, strSh = %s",szTitle,szCh,szSh);//没读取出来-_-
}

注册表编程

注册表存储在二进制文件里面,win32 API提供了大量的函数操作注册表。

创建注册表

RegCreateKeyW (
    //打开的当前项句柄,实际上就是那几个分支选项
    _In_ HKEY hKey,
    //打开或创建的表项的名称
    _In_opt_ LPCWSTR lpSubKey,
    //用来接收创建或者打开表项的句柄
    _Out_ PHKEY phkResult
    );

打开注册表

RegOpenKeyW (
    _In_ HKEY hKey,
    _In_opt_ LPCWSTR lpSubKey,
    _Out_ PHKEY phkResult
    );

写入注册表

RegSetValueW (
   //打开的当前项句柄,实际上就是那几个分支选项
    _In_ HKEY hKey,
    //打开或者创建的表项的名称
    _In_opt_ LPCWSTR lpSubKey,
    //指示被存储信息的类型REG_SZ类型
    _In_ DWORD dwType,
    //要存放到注册表里面的数据
    _In_reads_bytes_opt_(cbData) LPCWSTR lpData,
    //要存放的字符串数据的大小、长度
    _In_ DWORD cbData
    );

扩展——设置注册表项下指定值的数据和类型

RegSetValueExW(
    //打开的当前项的句柄,
    _In_ HKEY hKey,
    //指向一个字符串的指针,包含了将要设置值的名称
    _In_opt_ LPCWSTR lpValueName,
    //保留参数 0 
    _Reserved_ DWORD Reserved,
    //
    _In_ DWORD dwType,
    _In_reads_bytes_opt_(cbData) CONST BYTE* lpData,
    _In_ DWORD cbData
    );

从注册表中读取数据

RegQueryValueW (
    _In_ HKEY hKey,
    _In_opt_ LPCWSTR lpSubKey,
    //读取的缓存
    _Out_writes_bytes_to_opt_(*lpcbData, *lpcbData) __out_data_source(REGISTRY) LPWSTR lpData,
    //缓存大小
    _Inout_opt_ PLONG lpcbData
    );

示例:

//写注册表
void CMFCFileView::OnWriteReg()
{
    HKEY hKey;
    DWORD dwAge = 20;
    //创建注册表项 
    int ret = ::RegCreateKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Doraemon\\admin", &hKey);//创建失败,以管理员方式运行。
    if (ret)
    {
        TRACE("RegCreateKeyW Failed,ErrorCode = %d", GetLastError());
        MessageBox(L"创建注册表失败");
        return;
    }
    //写注册表
    ret = ::RegSetValueEx(hKey, L"age", 0, REG_DWORD, (CONST BYTE*) & dwAge, 4);
    if (ret != ERROR_SUCCESS)
    {
        TRACE("RegCreateKeyW Failed,ErrorCode = %d", GetLastError());
        MessageBox(L"写注册表失败");
        return;
    }
    ::RegCloseKey(hKey);
}

//读注册表
void CMFCFileView::OnReadReg()
{

    HKEY hKey;
    DWORD dwAge;
    //打开注册表项 
    int ret = ::RegCreateKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Doraemon\\admin", &hKey);//创建失败,以管理员方式运行。
    if (ret)
    {
        TRACE("RegOpenKeyW Failed,ErrorCode = %d", GetLastError());
        MessageBox(L"打开注册表失败");
        return;
    }
    //读注册表
    DWORD dwType;
    DWORD dwValue;

    ret = ::RegQueryValueEx(hKey, L"age", 0, &dwType, (LPBYTE) & dwAge, &dwValue);
    if (ret != ERROR_SUCCESS)
    {
        TRACE("RegQueryValueEx Failed,ErrorCode = %d", GetLastError());
        MessageBox(L"读注册表失败");
        return;
    }
    TRACE("dwType = %d,dwValue = %d,dwAge = %d",dwType,dwValue,dwAge);
    ::RegCloseKey(hKey);
}

文件操作的实际应用

  1. 调试日志debugview,文件日志:警告日志、错误日志。
  2. 视频存储
  3. 文件传输CFile和socket结合使用
  4. C语言和MFC的文件操作用途广泛,Win32 API、ifstream,ofstream用的少。
  5. 配置文件windows
  6. 注册表操作-病毒-逆向
0

评论区