这是好早前学习MSDN时留下的东西,现在把它放到新地方来
最近由于工作需要,一直在学习MSDN里面有关于服务编程的东西。整天看英文文档真是觉得无聊,所以我决定边看边翻译一下,也算是给学习留下一点成果吧。
程序使用CreateFile时,必须利用dwDesiredAccess参数来指明文件可读还是可写,或者可读写。这就是存取方式(access mode)。如果文件已经存在,程序也必须指定该做什么。比如说,程序可以以CREATE_ALWAYS为参数调用CreateFile,如果文件不存在,就创建新的文件,如果文件已经存在,就覆盖它。
程序也可以利用CreateFile来指定是否共享文件的读写。这就是共享方式。如果不是以共享模式打开文件,不管是打开它的程序或者其它的程序都不能再一次打开这个文件,除非这个文件的句柄被关闭。
当程序尝试打开一个已经以共享方式打开了的文件时,系统将请求权限以及共享方式和文件之前打开的时候做比较。如果存取方式和之前指定的有冲突,则CreateFile因共享违规(ERROR_SHARING_VIOLATION)失败。如果你选择的共享模式和之前指定的存取方式有冲突,则CreateFile因共享违规失败。
下面的表格举例说明了有效的存取方式和共享方式的组合。(注意第一行都是缩写,它应该是和第一列是一样的)
| G_R | G_R | G_R | G_W | G_W | G_W | G_R | G_R | G_R |
GENERIC_READ | Y |
| Y |
|
|
|
|
|
|
GENERIC_READ |
|
|
| Y |
| Y |
|
|
|
GENERIC_READ |
|
|
|
|
|
|
|
|
|
GENERIC_WRITE |
| Y | Y |
|
|
|
|
|
|
GENERIC_WRITE |
|
|
|
| Y | Y |
|
|
|
GENERIC_WRITE |
|
|
|
|
|
|
|
|
|
GENERIC_READ |
|
|
|
|
|
|
|
|
|
GENERIC_READ |
|
|
|
|
|
|
|
|
|
GENERIC_READ |
|
|
|
|
|
|
|
|
|
程序可以为创建的新文件提供一个模版文件,CreateFile函数可以从这个模版文件给新文件附加文件属性和一些额外属性。
创建新文件时,CreateFile函数执行以下几步:
1、明确存在的文件属性(CREATE_ALWAYS只用在文件已存在时)。
2、组合dwFlagsAndAttributes属性的文件属性和标志。
3、将文件的长度设置为零。
4、如果hTemplateFile参数被附值,则将额外的属性从模版文件拷贝到新文件。
5、依照lpSecurityDescriptor参数的SECURITY_ATTRIBUTES结构设置SD(将CREATE_ALWAYS用于已存在的文件时除外)。
6、依照dwCreationDisposition参数设置文件长度。
7、忽略hTemplateFile参数。
8、忽略SECURITY_ATTRIBUTES结构的lpSecurityDescriptor成员。其他成员被使用(比如,bInheritHandle声明这个文件句柄能否被继承)。
系统给每一个打开或者创建的文件附上一个唯一的标识,这就是文件句柄(file handle)。程序可以利用这个文件句柄读取,写入,表示文件。知道文件被关闭前,他都是有效的。如果句柄是可继承的,则当程序启动时,他从开启他的进程那里继承到所有打开可文件句柄。
程序必须先检验CreateFile函数的返回值,再通过句柄访问文件
。如果有错误发生,程序可以调用GetLastError函数获得错误信息。
例子:打开文件来读
下面的代码段使用CreateFile函数打开一个用来读取的文件。
#include <windows.h>
#include <stdio.h>
HANDLE hFile;
hFile = CreateFile(TEXT("myfile.txt"), // file to open
GENERIC_READ, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open file (error %d) ", GetLastError());
return 0;
}
在这种情况下,只有当前目录下已经存在myfile.txt时,CreateFile才会执行成功。之后的操作只有使用和CreateFile函数同样的存取和共享模式才会成功。
例子:打开文件来写
下面的代码段使用CreateFile函数来新建一个文件,来向里写数据。
#include <windows.h>
#include <stdio.h>
HANDLE hFile;
hFile = CreateFile(TEXT("myfile.txt"), // file to create
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_ALWAYS, // overwrite existing
FILE_ATTRIBUTE_NORMAL | // normal file
FILE_FLAG_OVERLAPPED, // asynchronous I/O
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open file (error %d) ", GetLastError());
return 0;
}
直到这个句柄没有关闭,之后使用CreateFile来打开这个文件都会失败。