文件操作
1.文件的读取与写入
新建一个MFC单文档应用程序(工程名取:File),打开菜单资源新建一个文件菜单,并在其下添加以下菜单项(ID:IDM_FILE_READ,Caption:读取)和(ID:IDM_FILE_WRITE,Caption:写入),并分别给它们添加CFileView类上的命令响应,编辑:
void CFileView::OnFileRead()
{
// TODO: Add your command handler code here
FILE *pFile=fopen("1.txt","r");//为了读取而打开一个文件
// char ch[100];
// memset(ch,0,100);
//将字符数组中所有的数据都设为零,这样读取时,就只读取到有字符的位置
// fread(ch,1,100,pFile);//读取文件
// MessageBox(ch);
char *pBuf;
fseek(pFile,0,SEEK_END);//将文件的指针移到文件的末尾
int len=ftell(pFile);//获取文件的大小
pBuf=new char[len+1];//根据文件的大小分配内存,多分配一个是为了存取'\0'
rewind(pFile);//这个函数可以将文件指针移到文件的开始处
fread(pBuf,1,len,pFile);//读取len所表示的文件的长度的数据
pBuf[len]=0;//将数组的最后个元素设置为0,因为数据索引是从0开始的,所以len表示最后一个
MessageBox(pBuf);
fclose(pFile);
//fflush(pFile);//刷新缓冲区,让缓冲区的数据写入文件
}
void CFileView::OnFileWrite()
{
// TODO: Add your command handler code here
FILE *pFile=fopen("1.txt","w");//为了写入而打开一个文件
fwrite("http://www.baidu.com",1,strlen("http://www.baidu.com"),pFile);
//把字符串写入文件
//fwrite("http://www.baidu.com",1,strlen("http://www.baidu.com")+1,pFile);
//为了让读取到指定字符就结束,+1是在文件中多写入一个字节,多写的字节为空,默认也是0,就是字符串的结尾
//fwrite("http://www.baidu.com",1,strlen("http://www.baidu.com"),pFile);
//还可以再次写入,位置是上次写入后文件指针所在的位置
//fseek(pFile,0,SEEK_SET);//将文件的指针位置设为零
//fwrite("ftp://10.6.17.19",1,strlen("ftp://10.6.17.19"),pFile);
//fclose(pFile);//关闭文件,表明文件的写操作已完成,缓冲区内容将写入文件
fflush(pFile);//刷新缓冲区,让缓冲区的数据写入文件
}
2.文件写入时经常会碰到的问题
void CFileView::OnFileWrite()
{
//FILE *pFile=fopen("2.txt","w");
FILE *pFile=fopen("2.txt","wb");
char ch[3];
ch[0]='a';
ch[1]=10;//10实际上指换行符
ch[2]='b';
fwrite(ch,1,3,pFile);//写入
fclose(pFile);
//运行可以发现在文件里写入了4个字节,回车符13占了两个字节
//转换成十六制可以发现:61 0D 0A 62 ;a..b
}
void CFileView::OnFileRead()
{
//FILE *pFile=fopen("2.txt","r");//缺省是按文本方式(t)打开
FILE *pFile=fopen("2.txt","rb");//以二进制方式(b)打开
char ch[100];
fread(ch,1,3,pFile);//读取文件
ch[3]=0;
MessageBox(ch);
fclose(pFile);
//以文本方式写入的文件
//以文本方式打开文件用3个字节读取发现仍然可以读出来
//以二进制方式用3个字符打开不能将b读出,只能读到61 0D 0A
//以二进制方式写入的文件
//以二进制方式用3个字符打开能将b读出
}
二进制文件和文本文件
3.一个问题
98341,将这个整数保存到文件中,要求在以记事本程序打开文件时,显示的是98341。
void CFileView::OnFileWrite()
{
FILE *pFile=fopen("3.txt","w");
int i=98341;
char ch[5];
/* ch[0]=9+48;//以ASCII码存进去
ch[1]=8+48;
ch[2]=3+48;
ch[3]=4+48;
ch[4]=1+48;
*/
itoa(i,ch,10);
//fwrite(&i,4,1,pFile);
fwrite(ch,1,5,pFile);
fclose(pFile);
}
===============================================
fopen, _wfopen
Open a file.
FILE *fopen( const char *filename, const char *mode );
FILE *_wfopen( const wchar_t *filename, const wchar_t *mode );
Function |
Required Header |
Compatibility |
fopen |
<stdio.h> |
ANSI, Win 95, Win NT |
_wfopen |
<stdio.h> or <wchar.h> |
Win NT |
For additional compatibility information, see Compatibility in the Introduction.
Libraries
LIBC.LIB |
Single thread static library, retail version |
LIBCMT.LIB |
Multithread static library, retail version |
MSVCRT.LIB |
Import library for MSVCRT.DLL, retail version |
The c, n, and t mode options are Microsoft extensions for fopen and _fdopen and should not be used where ANSI portability is desired.
Return Value
Each of these functions returns a pointer to the open file. A null pointer value indicates an error.
Parameters
filename
Filename
mode
Type of access permitted
Remarks
The fopen function opens the file specified by filename. _wfopen is a wide-character version of fopen; the arguments to _wfopen are wide-character strings. _wfopen and fopen behave identically otherwise.
Generic-Text Routine Mappings
TCHAR.H Routine |
_UNICODE & _MBCS Not Defined |
_MBCS Defined |
_UNICODE Defined |
_tfopen |
fopen |
fopen |
_wfopen |
The character string mode specifies the type of access requested for the file, as follows:
"r"
Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
"w"
Opens an empty file for writing. If the given file exists, its contents are destroyed.
"a"
Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn't exist.
"r+"
Opens for both reading and writing. (The file must exist.)
"w+"
Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.
"a+"
Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn't exist.
When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file. The file pointer can be repositioned using fseek or rewind, but is always moved back to the end of the file before any write operation is carried out. Thus, existing data cannot be overwritten.
The "a" mode does not remove the EOF marker before appending to the file. After appending has occurred, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file. The "a+" mode does remove the EOF marker before appending to the file. After appending, the MS-DOS TYPE command shows all data in the file. The "a+" mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.
When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for "update"). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, fseek, or rewind operation. The current position can be specified for the fsetpos or fseek operation, if desired.
In addition to the above values, the following characters can be included in mode to specify the translation mode for newline characters:
t
Open in text (translated) mode. In this mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing with "a+", fopen checks for a CTRL+Z at the end of the file and removes it, if possible. This is done because using fseek and ftell to move within a file that ends with a CTRL+Z, may cause fseek to behave improperly near the end of the file.
Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters (as if by a call to the mbtowc function). For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters (as if by a call to the wctomb function).
b
Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed.
If t or b is not given in mode, the default translation mode is defined by the global variable _fmode. If t or b is prefixed to the argument, the function fails and returns NULL.
For more information about using text and binary modes in Unicode and multibyte stream-I/O, see Text and Binary Mode File I/O and Unicode Stream I/O in Text and Binary Modes.
c
Enable the commit flag for the associated filename so that the contents of the file buffer are written directly to disk if either fflush or _flushall is called.
n
Reset the commit flag for the associated filename to "no-commit." This is the default. It also overrides the global commit flag if you link your program with COMMODE.OBJ. The global commit flag default is "no-commit" unless you explicitly link your program with COMMODE.OBJ.
Valid characters for the mode string used in fopen and _fdopen correspond to oflag arguments used in _open and _sopen, as follows.
Characters in mode String |
Equivalent oflag Value for _open/_sopen |
a |
_O_WRONLY | _O_APPEND (usually _O_WRONLY | _O_CREAT | _O_APPEND) |
a+ |
_O_RDWR | _O_APPEND (usually _O_RDWR | _O_APPEND | _O_CREAT ) |
r |
_O_RDONLY |
r+ |
_O_RDWR |
w |
_O_WRONLY (usually _O_WRONLY | _O_CREAT | _O_TRUNC) |
w+ |
_O_RDWR (usually _O_RDWR | _O_CREAT | _O_TRUNC) |
b |
_O_BINARY |
t |
_O_TEXT |
c |
None |
n |
None |
Example
/* FOPEN.C: This program opens files named "data"
* and "data2".It uses fclose to close "data" and
* _fcloseall to close all remaining files.
*/
#include <stdio.h>
FILE *stream, *stream2;
void main( void )
{
int numclosed;
/* Open for read (will fail if file "data" does not exist) */
if( (stream = fopen( "data", "r" )) == NULL )
printf( "The file 'data' was not opened\n" );
else
printf( "The file 'data' was opened\n" );
/* Open for write */
if( (stream2 = fopen( "data2", "w+" )) == NULL )
printf( "The file 'data2' was not opened\n" );
else
printf( "The file 'data2' was opened\n" );
/* Close stream */
if( fclose( stream ) )
printf( "The file 'data' was not closed\n" );
/* All other files are closed: */
numclosed = _fcloseall( );
printf( "Number of files closed by _fcloseall: %u\n", numclosed );
}
Output
The file 'data' was opened
The file 'data2' was opened
Number of files closed by _fcloseall: 1
===============================================
4.C++中对文件操作
void CFileView::OnFileWrite()
{
ofstream ofs("4.txt");//构造一个对象传递文件名4.txt
//C++中写入文件可以用这个类
ofs.write("www.baidu.com",strlen("www.baidu.com"));
ofs.close();
}
void CFileView::OnFileRead()
{
ifstream ifs("4.txt");//读入一个文件用这个类
char ch[100];
memset(ch,0,100);//将字符数组中的内存都设为零
ifs.read(ch,100);
ifs.close();
MessageBox(ch);
}
因为用到了ofstream和ifstream,所以还要在这个文件中包含头文件:
#include <fstream.h> //文件中用到了ofstream类,所以要包含这个头文件
5.win32API中对文件操作的几个函数
void CFileView::OnFileWrite()
{
HANDLE hFile;
hFile=CreateFile("5.txt",GENERIC_WRITE,0,NULL,
CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);//创建文件
DWORD dwWrites;//定义一个变量用来接收实际写入的字节数
WriteFile(hFile,"http://www.baidu.com",strlen("http://www.baidu.com"),
&dwWrites,NULL);
CloseHandle(hFile);//关闭文件,因为文件对象是用句柄来标识的
}
void CFileView::OnFileRead()
{
HANDLE hFile;
hFile=CreateFile("5.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);
char ch[100];
DWORD dwReads;//这个变量用来接收实际读取的字节数
ReadFile(hFile,ch,100,&dwReads,NULL);//读取文件
ch[dwReads]=0;//将实际数据的下一个数据设置为0
CloseHandle(hFile);
MessageBox(ch);
}
注:在win32 API中的CreateFile不光只是可以对文件进行操作,它还可以对其它的数据对象进行操作。
6.MFC当中对文件操作的类
void CFileView::OnFileWrite()
{
CFile file("6.txt",CFile::modeCreate|CFile::modeWrite);//定义一个CFile对象
file.Write("http://www.baidu.com",strlen("http://www.baidu.com"));//写入文件
}
void CFileView::OnFileRead()
{
CFile file("6.txt",CFile::modeRead);//以读模式创建一个文件
char *pBuf;
DWORD dwFileLen;
dwFileLen=file.GetLength();//获取文件长度
pBuf=new char[dwFileLen+1];
pBuf[dwFileLen]=0;//将pBuf中文件最后一字节的下一个字节置0
file.Read(pBuf,dwFileLen);
file.Close();
MessageBox(pBuf);
}
7.添加打开和另存为文件对话框
void CFileView::OnFileWrite()
{
CFileDialog fileDlg(FALSE);
//Set to TRUE to construct a File Open dialog box or FALSE to construct a File Save As dialog box
fileDlg.m_ofn.lpstrTitle="文件保存对话框";
fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";
//设置过滤器,\0表示字符串的结尾,过滤器的结尾要以\0\0结尾
fileDlg.m_ofn.lpstrDefExt="txt";//设置默认的扩展名
if(fileDlg.DoModal())
{
CFile file(fileDlg.GetFileName(),CFile::modeCreate|CFile::modeWrite);
file.Write("http://www.baidu.com",strlen("http://www.baidu.com"));//写入文件
file.Close();
}
}
void CFileView::OnFileRead()
{
CFileDialog fileDlg(TRUE);
//Set to TRUE to construct a File Open dialog box or FALSE to construct a File Save As dialog box
fileDlg.m_ofn.lpstrTitle="文件打开对话框";
fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";
//设置过滤器,\0表示字符串的结尾,过滤器的结尾要以\0\0结尾
if(fileDlg.DoModal())
{
CFile file(fileDlg.GetFileName(),CFile::modeRead);
char *pBuf;
DWORD dwFileLen;
dwFileLen=file.GetLength();//获取文件长度
pBuf=new char[dwFileLen+1];
pBuf[dwFileLen]=0;//将pBuf中文件最后一字节的下一个字节置0
file.Read(pBuf,dwFileLen);
file.Close();
MessageBox(pBuf);
}
}
8.将初始化信息写到ini文件中
在CFileApp::InitInstance()添加:
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
WriteProfileString("http://www.baidu.com","admin","luowei");//写入win.ini当中
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
9.读出ini文件中的信息
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
//::WriteProfileString("http://www.baidu.com","admin","luowei");//写入win.ini当中
CString str;
::GetProfileString("http://www.baidu.com","admin","win_ini",str.GetBuffer(100),100);
AfxMessageBox(str);
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
10.写入和读取注册表信息
在CFileApp::InitInstance()编辑,
写入:
//SetRegistryKey(_T("Local AppWizard-Generated Applications"));//设置注册表的位置
SetRegistryKey(_T("http://www.luowei.org"));//设置注册表的位置
WriteProfileString("http://www.baidu.com","admin","luowei");//写入注册表当中
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
读取:
SetRegistryKey(_T("http://www.luowei.org"));//设置注册表的位置
//WriteProfileString("http://www.baidu.com","admin","luowei");//写入注册表当中
CString str;
str=GetProfileString("http://www.baidu.com","admin");
AfxMessageBox(str);
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
11.注册表编程
在文件菜单下添加两菜单项,分别为:id:IDM_REG_WRITE(写注册表),id:IDM_REG_READ (读注册表) 。
写入和读取字符串类型的值
void CFileView::OnRegWrite()
{
// TODO: Add your command handler code here
HKEY hKey;
RegCreateKey(HKEY_LOCAL_MACHINE,"software\\http://www.luowei.org\\admin",&hKey);
//创建一个注册表项
RegSetValue(hKey,NULL,REG_SZ,"luowei",strlen("luowei"));
//设置注册表的值,第二个参数NULL,指定了缺省名字赋值
RegCloseKey(hKey);//关闭句柄
}
void CFileView::OnRegRead()
{
// TODO: Add your command handler code here
//获取字符串类型的数据
LONG lValue;
RegQueryValue(HKEY_LOCAL_MACHINE,"software\\http://www.luowei.org\\admin",NULL,&lValue);
//第三个参数设置为NULL,则返回注册表中注册表项的值的长度
char *pBuf=new char[lValue];//分配内存,lValue包含了多余的空字符,所以这不需要多分配一个字节
RegQueryValue(HKEY_LOCAL_MACHINE,"software\\http://www.luowei.org\\admin",pBuf,&lValue);
//获取注册表中注册表项的值
MessageBox(pBuf);
}
12.读取指定类型的注册表值
void CFileView::OnRegWrite()
{
HKEY hKey;
DWORD dwAge=30;
RegCreateKey(HKEY_LOCAL_MACHINE,"software\\http://www.luowei.org\\admin",&hKey);
//创建一个注册表项
RegSetValueEx(hKey,"age",0,REG_DWORD,(CONST BYTE*)&dwAge,4);
RegCloseKey(hKey);//关闭句柄
}
void CFileView::OnRegRead()
{
HKEY hKey;//用来存放打开的表项的返回值
RegOpenKey(HKEY_LOCAL_MACHINE,"software\\http://www.luowei.org\\admin",&hKey);
//打开注册表项
DWORD dwType;
DWORD dwValue;
DWORD dwAge;
RegQueryValueEx(hKey,"age",0,&dwType,(LPBYTE)&dwAge,&dwValue);
//获得注册表项的值
CString str;
str.Format("age=%d",dwAge);
MessageBox(str);
}