在Windows编程中CreateFile函数是用得非常多的,不仅可以打开文件,还可以打开管道、邮槽、通信资源、磁盘设备(早期Windows),控制台、目录。该函数返回一个句柄,该句柄可用于根据文件或设备以及指定的标志和属性访问文件或设备以获取各种类型的I/O。
打开文件
CreateFileW()函数
HANDLE CreateFileW(
[in] LPCWSTR lpFileName,
[in] DWORD dwDesiredAccess,
[in] DWORD dwShareMode,
[in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[in] DWORD dwCreationDisposition,
[in] DWORD dwFlagsAndAttributes,
[in, optional] HANDLE hTemplateFile
);
- 参数lpFileName
表示创建或打开的对象的名称
- 参数dwDesiredAccess
表示访问方式,可以读取、写入、两者、删除、所有这些或 无。下面是该参数可设置的值
取值 | 含义 |
---|---|
0 0x00000000 | 防止其他进程在请求删除、读取或写入访问权限时打开文件或设备。 |
FILE_SHARE_DELETE 0x00000004 | 对文件或设备启用后续打开操作以请求删除访问权限。 否则,如果其他进程请求删除访问权限,则无法打开文件或设备。 如果未指定此标志,但已打开文件或设备以进行删除访问,则函数 失败。 注意删除访问权限允许删除和重命名操作。 |
FILE_SHARE_READ 0x00000001 | 启用对文件或设备的后续打开操作以请求读取访问权限。 否则,如果其他进程请求读取访问权限,则无法打开文件或设备。 如果未指定此标志,但文件或设备已打开以进行读取访问,则函数 失败。 |
FILE_SHARE_WRITE 0x00000002 | 允许对文件或设备执行后续打开操作以请求写入访问权限。 否则,如果其他进程请求写入访问权限,则无法打开文件或设备。 如果未指定此标志,但文件或设备已打开以进行写入访问或具有文件映射 使用写入访问权限时,函数将失败。 |
- 参数dwShareMode
表示共享方式,如果某一种访问方式设置为不共享,那么后续如果还有这种方式访问时将会打开失败。
- 参数lpSecurityAttributes
NULL表示默认安全属性,但是不会被子进程继承
- 参数dwCreationDisposition
表示如何创建文件,下面是该参数可设置的值。
取值 | 意义 |
---|---|
CREATE_ALWAYS 2 | 始终创建新文件。 如果指定的文件存在且可写,则该函数将覆盖该文件,该函数将成功,并且 最后一个错误代码设置为ERROR_ALREADY_EXISTS(183)。 如果指定的文件不存在并且是有效路径,则创建一个新文件,函数成功,并且 最后一个错误代码设置为零。 有关详细信息,请参阅本主题的“备注”部分。 |
CREATE_NEW 1 | 仅当文件尚不存在时才创建新文件。 如果指定的文件存在,则函数将失败,并且最后一个错误代码设置为ERROR_FILE_EXISTS(80)。 如果指定的文件不存在,并且是可写位置的有效路径,则会创建一个新文件。 |
OPEN_ALWAYS 4 | 始终打开文件。 如果指定的文件存在,则函数成功,并将最后一个错误代码设置为ERROR_ALREADY_EXISTS(183)。 如果指定的文件不存在,并且是可写位置的有效路径,则该函数将创建一个 文件,最后一个错误代码设置为零。 |
OPEN_EXISTING 3 | 仅打开文件或设备(如果存在)。 如果指定的文件或设备不存在,则该函数将失败,并且最后一个错误代码设置为ERROR_FILE_NOT_FOUND(2)。 有关设备的详细信息,请参阅“备注”部分。 |
TRUNCATE_EXISTING 5 | 打开文件并将其截断,使其大小为零字节(仅当它存在时)。 如果指定的文件不存在,则该函数将失败,并且最后一个错误代码设置为ERROR_FILE_NOT_FOUND(2)。 调用进程必须打开将GENERIC_WRITE位设置为一部分的文件 dwDesiredAccess参数。 |
- 参数dwFlagsAndAttributes
设置文件的属性和标志,FILE_ATTRIBUTE_NORMAL是最多的 文件的通用默认值。
- 参数hTemplateFile
此参数可以直接为NULL。
写文件
WriteFile() 函数
BOOL WriteFile(
[in] HANDLE hFile,
[in] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[out, optional] LPDWORD lpNumberOfBytesWritten,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
- 参数hFile
文件或设备句柄
- 参数lpBuffer
写入数据的缓冲区指针
- 参数nNumberOfBytesToWrote
写入文件或设备的字节数
- 参数lpNumberOfBytesWritten
指向变量的指针,该变量接收使用同步hFile参数时写入的字节数。
- 参数lpOverlapped
指向重叠结构的指针是 如果使用FILE_FLAG_OVERLAPPED 打开hFile参数,则为必需,否则此参数可以为NULL。
读文件
ReadFile( )函数
BOOL ReadFile(
[in] HANDLE hFile,
[out] LPVOID lpBuffer,
[in] DWORD nNumberOfBytesToRead,
[out, optional] LPDWORD lpNumberOfBytesRead,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
- 参数hFile
设备句柄
- 参数lpBuffer
接收数据缓冲区的指针
- 参数nNumberOfBytesToRead
读取的最大字节数
- 参数lpNumberOfBytesRead
指向变量的指针,用来接收使用同步hFile参数读取的字节数。
- 参数lpOverlapped
重叠结构的指针,使用FILE_OVERLAPPED打开hFile参数,则为必须,否则可为NNULL
Demo示例
写文件:
程序通过CreateFile函数打开文件,函数返回一个句柄。当使用WriteFile函数时通过该句柄向文件写入内容
void CMyFileCFileView::OnFileWrite() {
HANDLE hFile = CreateFile(
L"3.txt", //要打开的文件名
GENERIC_WRITE, //访问方式
0, //共享方式
NULL, //安全属性
CREATE_NEW, //仅打开文件或设备
FILE_ATTRIBUTE_NORMAL,//正常文件
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
TRACE("#INVALUD_HANDLE_VALUD ,errorcode = %d", GetLastError());
return;
}
//写文件
DWORD dwWrites;
WriteFile(
hFile,
"Hello World",
strlen("Hello World"),
&dwWrites, //用来接收实际写入到文件的字节数,有可能要求写入的和实际写入的不一样
NULL
);
TRACE("#dwWrites = %d", dwWrites);
CloseHandle(hFile);
}
读文件:
程序通过CreateFile函数打开文件,函数返回一个句柄。当使用ReadFile函数时通过该句柄读取文件内容,并通过消息框将读取内容显示出来。
void CMyFileCFileView::OnFileRead() {
HANDLE hFile = CreateFile(
L"3.txt", //要打开的文件名
GENERIC_READ, //访问方式
0, //共享方式
NULL, //安全属性
OPEN_EXISTING, //仅打开文件或设备
FILE_ATTRIBUTE_NORMAL,//正常文件
NULL
);
DWORD dwWrites;
char pBuf[100] = { 0 };
ReadFile(
hFile,
pBuf,
100,
&dwWrites, //用来接收实际写入到文件的字节数,有可能要求写入的和实际写入的不一样
NULL
);
USES_CONVERSION;
CString strBuf = A2W(pBuf);
MessageBox(strBuf);
CloseHandle(hFile);
}