MFC文件和注册表的操作

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

Linux下一切皆文件。

C/C++文件操作

常量指针和指针常量

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

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

C语言文件操作

文件打开的模式

【MFC】 MFC文件操作和注册表操作_配置文件

示例:

//写文件
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类

【MFC】 MFC文件操作和注册表操作_配置文件_02

//写文件
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);
}
}

【MFC】 MFC文件操作和注册表操作_c++_03

配置文件的访问与读写

示例:

//写配置文件
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. 注册表操作-病毒-逆向