MFC文件操作

文件操作:二进制文件和文本文件的区别。二进制文件将数据在内存中存在的模式原封不动的搬到文件中,而文本文件是将数据的asc码搬到文件中。
首先做一个读写文件的菜单,在CxxView里响应
1.C的方式:
fwrite:
size:Item size in bytes 每次写多少个字节
count:Maximum number of items to be written ,总共写几次。

FILE *p;
p=fopen("c://1.txt","w");
fwrite("abc",1,4,p);
fclose(p);
由于我们打开文件后文件就被映射到内存中的缓存中,我们对文件所做的操作都是在内存中完成的,如果我们不关闭文件,则内存中对文件所做的修改就不会反映(保存)到硬盘中,除非你把当前一个应用程序关闭,这是会自动执行文件关闭的操作。
fflush可以在文件不关闭的情况下将一个流(缓冲区)当中的数据清空,这里的清空是把缓冲区的数据输出到硬盘。这样可以达到边写边输出的效果。
FILE* pFile=fopen("c://1.txt","w"); 
fwrite("何问起网",1,strlen("何问起网"),pFile);
//fclose(pFile);
fflush(pFile);
fwrite("how are you",1,strlen("何问起网"),pFile);
fflush(pFile);
fclose(pFile);
我们发现下一次的“h”是写在了上次的“心”后面了,这是因为,对于文件来说它有一个文件字符位置的指针,这个指针不同于文件的指针,是文件结构中这个char *_ptr;成员。当我们写完“心”字后,这个指针就在“心” 字后,所以下次写“h”的时候就是在“心”的后面写。如果想将第二句在“维”的前面输出,则要移动文件的位置指针,用fseek
FILE* pFile=fopen("c://1.txt","w"); 
fwrite("何问起网",1,strlen("何问起网"),pFile);
//fclose(pFile);
fflush(pFile); 
fseek(pFile,0,SEEK_SET);
fwrite("北京",1,strlen("北京"),pFile);
fflush(pFile);
fseek(pFile,0,SEEK_END);
CString str;
str.Format("文件大小:%d",ftell(pFile));
MessageBox(str);
fclose(pFile);
读文件
FILE* pFile=fopen("c://1.txt","r"); 
char buf[100];
fread(buf,1,100,pFile);//虽然读出的数据超出了实际字符串的长度,但输出时还是找’/0’
MessageBox(buf);
fclose(pFile);
出现了乱码,是因为输出文件的时候没有及时找到’/0’.将写文件的strlen改为sizeof
文件读写函数需要读写的时候将’/0’带上,它类似于printf和strlen等函数以’/0’作为函数结束表示。
乱码的解决也可以用
FILE* pFile=fopen("c://1.txt","r"); 
char buf[100];
fseek(pFile,0,SEEK_END);
long len=ftell(pFile);
rewind(pFile);
fread(buf,1,len,pFile);
buf[len]=0;
MessageBox(buf);
fclose(pFile);
第三种方法:
FILE* pFile=fopen("c://1.txt","r"); 
char buf[100];
memset(buf,0,100);//可以用任意的字符来填充这个内存块。
ZeroMemory(buf,100);// 只能用‘/0’字符来填充这个内存块。
fread(buf,1,100,pFile);
MessageBox(buf);
fclose(pFile);
2.C++的方式:#include "fstream.h"
写:
ofstream ofs("c://1.txt");
ofs.write("何问起网",sizeof("何问起网"));
ofs.close();//最好自己将文件关掉,不关也行,这个filebuf对象的析构函数为你关。
读:
ifstream ifs("c://1.txt");
char buf[100];
ifs.read(buf,100);
MessageBox(buf);
当我们写的代码改为                          
ofstream ofs("c://1.txt");
char str[3];
str[0]=‘a‘;
str[1]=10;
str[2]=‘b‘;
ofs.write(str,sizeof(str));
   ofs.seekp(0);
ofs.write("china",sizeof("china"));
发现此时默认按照文本写和读的时候,文件的大小不符。
这是因为在用文本文件方式读写的时候,碰到了asc码为10的字符,都将被转换,写文件的时候将10前面加上13写到了文件中,读文件读到13和10,将这两个字符换成一个10.注意在用ultraEdit看的时候不要转成DOS格式。
如果以二进制文件(ios::binary)进行读写的时候就没有这种问题存在。不做任何的转换。
C++的文件操作打开文件是在构造函数里完成,关闭文件是在析构函数里完成。
3. MFC的方式:
I. 写文件:
CFile f("c://1.txt",CFile::modeWrite|CFile::modeCreate);
f.Write("hello",5);
a.几个标志的作用:
  CFile::modeCreate:没有指定的文件就产生一个新文件,有就打开该文件,并将它裁剪到0;
  CFile::modeNoTruncate :打开文件时不裁剪到0;
b.写数据到文件末尾:
CFile f("c://1.txt",CFile::modeWrite|CFile::modeCreate|
CFile::modeNoTruncate);
      f.SeekToEnd();
f.Write("hello",5);
//file.Close();如果我不关闭的话,其析构函数会为我关闭。
II. 读文件:
CFile f("c://1.txt",CFile::modeRead);
char buf[10];
memset(buf,0,10);
f.read(buf,5);
MessageBox(buf);
III. 文件对话框:
保存对话框:

CFileDialog fdlg(false);
//fdlg.m_ofn.lpstrTitle="何问起造!";
fdlg.m_ofn.lpstrDefExt="txt";
fdlg.m_ofn.lpstrFilter="文本文件 (*.txt)/0*.txt/0所有文件 (*.*)/0*.*/0/0";
if(IDOK==fdlg.DoModal())
{
//MessageBox(fdlg.GetFileName());
CFile file(fdlg.GetFileName(),CFile::modeCreate|CFile::modeWrite);
file.Write("何问起网",sizeof("何问起网"));
file.Close();
}

打开对话框:

CFileDialog fdlg(true);
//fdlg.m_ofn.lpstrTitle="何问起造!";
fdlg.m_ofn.lpstrFilter="文本文件 (*.txt)/0*.txt/0所有文件 (*.*)/0*.*/0/0";
if(IDOK==fdlg.DoModal())
{  
CFile file(fdlg.GetFileName(),CFile::modeRead);
char buf[100];
file.Read(buf,100);
MessageBox(buf);
}
2. 文本文件和二进制文件的区别:
文件文件是一种特殊的二进制文件,当它遇到回车键10时,写入文件时会自动地在它的前面加一个13,而读出文件时遇到13 10 的组合时,又把它还原到10。而二进制文件就是把数据原封不动的写入文件,原封不动的再读取出来,没有文本文件的这种转换操作。
下面的代码演示了之间的这种区别:
  写入文件时:
   ofstream f("c://1.txt");
   char buf[3];
   buf[0]=‘a‘;
   buf[1]=‘/n‘;
   buf[2]=‘b‘;
   f.write(buf,3);
读出文件时:
ifstream f("c://1.txt");
f.setmode(filebuf::binary);
char buf[5];
memset(buf,0,5);
f.read(buf,5);
CString str;
str.Format("%d,%d,%d,%d",buf[0],buf[1],buf[2],buf[3]);
MessageBox(str);
    在写入文件时不指定格式,文件将按文本格式存储,此时读出文件时指定二进制格式,读出的数据如下图:
      
如果注释f.setmode(filebuf::binary);语句,文件将按文本文件读出,如下图:

二、 注册表的操作
1. 读写win.ini文件:
使用API的GetProfileInt和WriteProfileString来实现一个保存窗口大小的例子。
在CMainFrame的
void CMainFrame::OnDestroy() 
{
CFrameWnd::OnDestroy();

// TODO: Add your message handler code here
CRect rect;
GetWindowRect(&rect);
CString str;
str.Format("%d",rect.Width());
WriteProfileString("窗口尺寸","宽度",str);
str.Format("%d",rect.Height());
WriteProfileString("窗口尺寸","高度",str);
}

在CMainFrame的
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
   return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.cx=GetProfileInt("窗口尺寸","宽度",100);
cs.cy=GetProfileInt("窗口尺寸","高度",100);
return TRUE;
}

演示使用API的GetProfileString.对于它的第四个参数lpReturnedString需要添一个char*来返回。这里不能添CString对象来返回,这是一个特殊的地方。别的函数一般要char*的时候都可以用CString对象来代替。
这里我们用CString的GetBuffer来添这个char*。
A CString object consists of a variable-length sequence of characters.
因为一个字符串对象由一序列长度可变的字符组成。

Returns a pointer to the internal character buffer for the CString object. The returned LPTSTR is not const and thus allows direct modification of CString contents.
返回一个CString对象内部字符的缓冲区(字符数组)的指针,这个返回的指针不是一个常量的指针,因而允许直接修改指针所指向的CString对象的内容。这个指针和CString内部字符数组的地址是相等的。

If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString member functions.
如果你使用这个通过GetBuffer返回的指针改变了字符串的内容,你在使用CString其他成员函数之前必须调用ReleaseBuffer。

在CWinApp的InitInstance里
CString str;
::GetProfileString("窗口尺寸","高度","无值",str.GetBuffer(100),100);
AfxMessageBox(str);
下面测试CWinApp的WriteProfileString,GetProfileString。
对于WriteProfileString有段说明
· In Windows NT, the value is stored to a registry key.
· In Windows 3.x, the value is stored in the WIN.INI file. 
· In Windows 95, the value is stored in a cached version of WIN.INI
在CWinApp的InitInstance里
WriteProfileString("收藏","vc++","菜鸟");

CString str;
str=GetProfileString("收藏","vc++","无效值");
AfxMessageBox(str);
所以这里写的话是写到了HKEY_CURRENT_USER/Software/Local AppWizard-Generated Applications/MyFile/维新里。

实现一个简单的计数器,来限制软件的使用次数:
SetRegistryKey(_T("myboleApp"));
int x=GetProfileInt("test","times",0);
if(x>=5)
   return false;
WriteProfileInt("test","times",++x);
CString str;
str.Format("你还能使用%d次",5-x);
AfxMessageBox(str);

2. 读写WIN32注册表,做两个菜单进行注册表的读写操作,写的时候先打开所要操作键,也就是返回操作键的句柄用RegCreateKey(这个句柄包含主键和子键,第一个参数可以是一个已打开的句柄或者一个预定义的保留的句柄值,如果是前面这个已打开的句柄,那么可以根据这个已打开句柄和后面子键的参数,在这个已打开键的下面创建一个新的句柄),然后根据得到的这个句柄去读写。
在使用RegSetValue进行写操作的时候,写的类型必须是REG_SZ,这个类型可以理解成已’/0’结尾的字符串,如果我们想写别的数据类型,使用RegSetValueEx.
The RegSetValue function sets the data for the default or unnamed value of a specified registry key. The data must be a text string.
RegSetValue函数为默认的或没有名字的指定的注册表键设置数据,这个数据必须是字符串。
RegSetValue最后一个参数不包括’/0’
使用新函数在注册表任意位置读写:
写:
HKEY hKey;
RegCreateKey(HKEY_LOCAL_MACHINE,"software//收藏",&hKey);
//RegSetValue(hKey,NULL,REG_SZ,"WeiXin",6);
//RegSetValue(hKey,"课程",REG_SZ,"WeiXin",6);
DWORD i=100;//下面的参数要的是地址,所以这里要定义这个变量
RegSetValueEx(hKey,"JSP",NULL,REG_DWORD,(CONST BYTE*)&i,4);
RegCloseKey(hKey);
读:in bytes以字节为单位

读一个默认键的值:
char *buf;
long len;
RegQueryValue(HKEY_LOCAL_MACHINE,
"software//何问起网//mylyhu//abc",NULL,&len);
buf=new char[len];
RegQueryValue(HKEY_LOCAL_MACHINE,
"software//何问起网//mylyhu//abc",buf,&len);
MessageBox(buf);
delete [] buf;

RegQueryValue参数说明:
If lpValue is NULL, and lpcbValue is non-NULL, the function returns ERROR_SUCCESS, and stores the size of the data, in bytes, in the variable pointed to by lpcbValue. This lets an application determine the best way to allocate a buffer for the value‘s data. 
如果lpValue是NULL,并且lpcbValue不是NULL,这个函数返回ERROR_SUCCESS,并且通过lpcbValue所代表这个变量的指针存储数据的字节单位的的大小,这是让一个应用程序按照最好的方式去为查询值的数据分配空间

读一个有名字的键的值。
HKEY hKey;
RegCreateKey(HKEY_LOCAL_MACHINE,"software//维新",&hKey); 
DWORD dwType;
DWORD data;
DWORD len=4;
RegQueryValueEx(hKey,"JSP",NULL,&dwType,(BYTE*)&data,&len);
CString str;
str.Format("%d",data);
MessageBox(str);
::RegCloseKey(hKey);

锁注册表:
HKEY hKey;
RegCreateKey(HKEY_CURRENT_USER,"software//microsoft//windows//currentversion//policies//system",&hKey);
DWORD x=1;
RegSetValueEx(hKey,"DisableRegistryTools",0,REG_DWORD,(CONST BYTE*)&x,4);
RegCloseKey(hKey);

解注册表
HKEY hKey;
RegCreateKey(HKEY_CURRENT_USER,"software//microsoft//windows//currentversion//policies//system",&hKey);
DWORD x=0;
RegSetValueEx(hKey,"DisableRegistryTools",0,REG_DWORD,(CONST BYTE*)&x,4);
RegCloseKey(hKey);

推挤:http://www.cnblogs.com/roucheng/p/cppyiwei.html

时间: 2024-11-05 15:49:46

MFC文件操作的相关文章

MFC文件操作、序列化机制

一 MFC的文件操作 1 相关类 CFile类-封装了文件句柄以及操作文件的API函数. CFileFind类-封装了文件搜索功能. 2CFile类的使用 2.1 文件读写 2.1.1 创建或者打开文件 CFile::Create 2.1.2 文件读写 CFile::Read/Write 2.1.3 关闭文件 CFile::Close 注意:1 文件读写需要异常处理 2 注意文件的指针位置 2.2 文件属性的获取和设置 2.2.1 CFile::GetStatus 2.2.2 CFile::Se

MFC 文件操作

MFC中文件的建立 在操作系统中,文件是放在一定的目录下,在创建以及操作文件以前,我们要查看文件要保存的目录有没有存在,如果不存在要创建.这就要用到GetFileAttributes()和CreateDirectory()两个函数.下面是这两个函数的简介: 1.GetFileAttributes 函数原型: DWORD WINAPI GetFileAttributes( __in LPCTSTR lpFileName ); 函数参数 lpFileName [in] :文件或目录的名字,对于ANS

文件操作

1.C文件操作 2.c++文件操作 3.MFC文件操作:CFile是MFC的文件操作基本类,它直接支持无缓冲的二进制磁盘I/O操作,并通过其派生类支持文本文件.内存文件和socket文件. Visual C++处理的文件通常分为两种: 文本文件:只可被任意文本编辑器读取ASCII文本. 二进制文件:指对包含任意格式或无格式数据的文件的统称. 1.定义文件变量 定义文件变量格式:CStdioFile 文件变量: 例如,定义一个名称为f1的文件变量,语句如下:CStdioFile f1; 2.打开指

MFC文件夹以及目录常见操作

CString CCallSchedulingSystemDlg::GetFilePath(void) { HMODULE module = GetModuleHandle(0); char pFileName[MAX_PATH]; GetModuleFileName(module, pFileName, MAX_PATH); CString csFullPath(pFileName); int nPos = csFullPath.ReverseFind( _T('\\') ); if( nPo

C++MFC编程笔记day07 MFC的文件操作、序列化和保存

一 MFC的文件操作 1 相关类 CFile类-封装了文件句柄以及操作文件的API函数. CFileFind类-提供文件查找功能. 2 CFile类的使用 2.1 打开或者新建文件 CFile::Open 2.2 文件读写 注意:1 文件指针位置 2 异常处理 CFile::Write CFile::Read CFile::SeekToBegin 2.3 关闭文件 CFile::Close 2.4 设置/获取文件属性 CFile::SetStatus/GetStatus 3 CFileFind类

个人的后门程序开发(第一部分):文件操作和注册表管理

本来是想寒假时写的,结果一直懒得动手. 虽然手上有ghost源码,但是感觉功能不是我想要的,比如把精力费在学MFC写界面上不如改进下隐藏性. 基本的计划就是做一个后门程序,目的是用来进行权限维持的.目前来看是基于控制台的,而且要带有内核模块,应用层的主要问题就是没写过太大体量的程序导致搞起来很蛋疼,内核方面就是通用性坑爹, 蓝屏起来也要费时间. 第一部分就是封装的两个函数,文件操作和注册表管理.ghost是把这两个功能封装成两个类,我这里就直接用函数来实现了. VS2015编译通过 1 //文件

C++ 文件操作(CFile类)

原文:文件操作(CFile),C吉羊 一.Visual C++编程文件操作 有如下方法可进行操作: (1)使用标准C运行库函数,包括fopen.fclose.fseek等. (2)使用Win16下的文件和目录操作函数,如lopen.lclose.lseek等.不过,在Win32下,这些函数主要是为了和Win16向后兼容. (3)使用Win32下的文件和目录操作函数,如CreateFile,CopyFile,DeleteFile,FindNextFile,等等. Win32 下,打开和创建文件都由

MFC文件读写

MFC文件读写 分类: c++2009-09-24 23:30 12400人阅读 评论(4) 收藏 举报 mfcdllinifile存储windows 目录(?)[-] 为什么要在程序中使用文件 文件类型 第一部分文本文件 文本文件的读写 客户操作记录实例功能预览及关键知识点 文本文件存储管理 正确的文本文件读写过程 定义文件变量 打开指定文件 实例1以只读方式打开一个文件 向从文本文件中写入信息 实例2向文件中写入文本 从文本文件中读取信息 实例3从文件中读取文本信息 关闭文件 错误的文本文件

UNICODE环境下读写txt文件操作

内容转载自http://blog.sina.com.cn/s/blog_5d2bad130100t0x9.html UNICODE环境下读写txt文件操作 (2011-07-26 17:40:05) 标签: 杂谈 分类: MFC程序设计 自己动手整理了一下,写了几个函数,用于UNICODE环境下对txt文本文件的操作,针对txt文本的ANSIC编码格式,进行了字符编码格式的转换.***********************************************************