C++和Win32API 文件操作
(2010-08-27 16:51:38)
标签:
杂谈 |
分类: C 和MFC |
我们需要一个头文件 #include "fstream.h"
在C++,进行文件操作,写入数据,我们需要用到一个函数ofstream。
ofstream( const char* szName, int nMode = ios::out, int nProt = filebuf::openprot );
第一个参数,要打开的文件名,第二个参数打开的方式,有自己的参数列表:
- ios::app
- ostream::seekp
-
ios::ate
-
ios::in
-
ios::out
-
ios::trunc
-
ios::nocreate
-
ios::noreplace
-
ios::binary
第三个参数,文件保护的说明。也有自己的参数列表:
-
filebuf::sh_compat
-
filebuf::sh_none
- filebuf::sh_read
- filebuf::sh_write
读取文件的时候我们用ifstream这个类:
ifstream( const char* szName, int nMode = ios::in, int nProt = filebuf::openprot );
- ios::in
- ios::nocreate
- ios::binary
我们看一下写入和读取的例子:
//写入
ofstream ofs("4.txt"); //构造一个对象
//读取
ifstream ifs("4.txt");
//memset一般是用于初始化(清空)一个内存块,以防你新建一个变量等时系统分配给你一段含有用过的内存
//块。如果某君不小心不另外对其初始化就调用的话,可能会产生不可预料的错误。
我们看一下Win32API中对文件操作的几个函数:
首先我们看一下打开文件的函数:
HANDLE CreateFile(
);
我们可以看到这个函数返回一个句柄。来表示打开或者创建对象的句柄
第一个参数,文件名
第二个参数,访问的方式,有两个参数:
GENERIC_READ
GENERIC_WRITE
第三个参数,共享方式:
指定文件对象如何被共享,参数如果为零,对象不能被共享
第四个参数,指向SECURITY_ATTRIBUTES结构体的指针,用来确定返回的句柄,是否能被子进程所继承。用来指定我们所创建文件对象访问权限,以及返回对象的句柄是否能被子进程所继承。
我们看一下这个结构体
typedef struct _SECURITY_ATTRIBUTES { // sa
} SECURITY_ATTRIBUTES
第四个参数设为NULL,创建的带有默认安全性的对象,返回的文件对象的句柄,是不能被继承的。
第五个参数,如何创建:有自己的参数
CREATE_NEW //创建一个新文件,如果文件存在,这个函数失败
CREATE_ALWAYS//创建一个文件,如果文件存在函数覆盖这个文件,清除现有属性
OPEN_EXISTING
OPEN_ALWAYS
TRUNCATE_EXISTING
第六个参数,文件属性。
FILE_ATTRIBUTE_ARCHIVE
FILE_ATTRIBUTE_HIDDEN
FILE_ATTRIBUTE_NORMAL
FILE_ATTRIBUTE_OFFLINE
FILE_ATTRIBUTE_READONLY
FILE_ATTRIBUTE_SYSTEM
FILE_ATTRIBUTE_TEMPORARY
FILE_FLAG_WRITE_THROUGH
FILE_FLAG_OVERLAPPED
FILE_FLAG_NO_BUFFERING
FILE_FLAG_RANDOM_ACCESS
FILE_FLAG_SEQUENTIAL_SCAN
FILE_FLAG_DELETE_ON_CLOSE
FILE_FLAG_BACKUP_SEMANTICS
FILE_FLAG_POSIX_SEMANTICS
FILE_FLAG_OPEN_REPARSE_POINT
FILE_FLAG_OPEN_NO_RECALL
为我们的文件设置文件属性和标记,可以去以上几个值。我们可以用最普通的一个值:FILE_ATTRIBUTE_NORMAL
作用,如果说我们传递了一个文件句柄,那么第六个参数的文件属性将被忽略,而是用GENERIC_READ所标识的文件的属性。
有了这些,我们新建一个句柄:
HANDLE hFile;
创建一个文件:
CreateFile("5.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
然后用到一个写入文件的函数:
BOOL WriteFile(
);
第一个参数 文件的一个句柄,
第二个参数 是一个指针,指向一个buffer,将要写入文件的数据
第三个参数 将要写多少个字节
第四个参数 指向一个变量来接收实际写入到文件的字节数。
最后一个参数 指向 Overlapped结构体的指针。
最后一个参数想要起作用,在我们打开文件的时候,设置文件属性的时候,我们需要加上一个标记。
FILE_FLAG_OVERLAPPED设置这个标识,就是告诉系统,我们想要异步的去访问一个文件。如果没有设置这个标记
我们打开文件是同步IO的方式
我们要了解一下同步和异步。同步IO就是我们写入数据或者读取数据的时候,如果数据没有完整的写入到文件中,或者没有读完,程序将被挂起,知道写入完成,读取完成,程序才能继续运行。而我们设置了这个标记,异步IO方式告诉操作系统,读写数据不必等到IO结束,函数调用立即返回。返回了,但是读写操作没有完成怎么办呢,操作系统会使用线程我们完成这个IO。当操作系统完成了IO操作时,我们会得到通知。
我们再打开文件的时候并没有设置FILE_FLAG_OVERLAPPED.
所以我们调用WriteFile时,最后一个参数设置为NULL 。
HANDLE hFile;//定义一个句柄
//打开一个文件,获得文件的句柄,这里是创建一个文件
接下来是读取文件。
大部分跟写入相同,这里我们需要一个函数ReadFile来读取文件
BOOL ReadFile(
HANDLE hFile, // handle of file to read
LPVOID lpBuffer, // pointer to buffer that receives data
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read
LPOVERLAPPED lpOverlapped // pointer to structure for data
);
HANDLE hFile;