文章目录
- 前言
- 一、文件的创建与打开CreateFile
- 1. 创建新的空白文件
- 2. 打开已存在文件
- 3. 打开一个文件时,如果文件存在则打开,如果文件不存在则新创建文件
- 4.打开一个文件,如果文件存在则打开文件并清空内容,文件不存在则 新创建文件
- 二、关闭文件句柄CloseHandle
- 总结
前言
Windows 程序设计7:文件的创建、打开与关闭。
一、文件的创建与打开CreateFile
Windows系统中文件的创建与打开都是使用同一个API函数CreateFile。通过传递不同的参数值来表示是要创建一个新文件还是要打开一个已经存在的文件。函数原型如下:
HANDLE CreateFile(LPCTSTR lpFileName, // 文件名或设备名DWORD dwDesiredAccess, // 访问模式DWORD dwShareMode, // 共享模式LPSECURITY_ATTRIBUTES lpSecurityAttributes,// 安全属性DWORD dwCreationDisposition,// 创建方式DWORD dwFlagsAndAttributes, // 文件属性HANDLE hTemplateFile // 模板文件句柄
);
// 该函数用于打开文件或I/O设备,常见的I/O设备有:
// 文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、邮筒和管道等
返回值:该函数返回一个句柄,该句柄可以根据文件或设备,以及指定的标志和属性访问文件或设备以获取各种类型的I/O。如果成功,返回文件或设备的句柄;如果失败,返回 INVALID_HANDLE_VALUE。可以通过 GetLastError 获取错误代码。文件或设备的句柄就相当于其代号,有了句柄之后就可以对其进行其他操作。
参数说明:
1.参数lpFileName:LPCTSTR类型
要创建或打开的文件的路径(可以是绝对路径或相对路径)。
也可以是设备名(如 COM1、LPT1)。
2.dwDesiredAccess:DWORD类型
指定对文件的访问权限,创建或打开这个文件之后我们要对这个文件干什么,就赋予相应的权限。常见值:
GENERIC_READ:读取权限。
GENERIC_WRITE:写入权限。
GENERIC_READ | GENERIC_WRITE:读写权限。
0:不希望从设备读取数据或向设备传入数据
3.dwShareMode:DWORD类型
指定文件的共享模式。常见值:
FILE_SHARE_READ:允许其他进程读取文件。
FILE_SHARE_WRITE:允许其他进程写入文件。
FILE_SHARE_DELETE:允许其他进程删除文件。
0:独占访问,不允许其他进程访问。
4.lpSecurityAttributes:LPSECURITY_ATTRIBUTES类型
指向 SECURITY_ATTRIBUTES 结构的指针,用于设置文件的安全属性。
通常设置为 NULL,表示使用默认安全属性。
5.dwCreationDisposition:DWORD类型
指定文件存在或不存在时的操作。常见值:
CREATE_NEW:创建新文件,如果文件已存在则失败。
CREATE_ALWAYS:创建新文件,如果文件已存在则覆盖。
OPEN_EXISTING:打开现有文件,如果文件不存在则失败。
OPEN_ALWAYS:打开文件,如果文件不存在则创建。
TRUNCATE_EXISTING:打开文件并将其截断为 0 字节(清空文件内容),如果文件不存在则失败。
6.dwFlagsAndAttributes:DWORD类型
指定文件属性和标志。允许我们设置一些标志来微调与设备之间的通信,如果设备是一个文件,还能够设置文件的属性。常见值:
FILE_ATTRIBUTE_NORMAL:普通文件,无特殊属性。
FILE_ATTRIBUTE_HIDDEN:隐藏文件。
FILE_ATTRIBUTE_READONLY:只读文件。
FILE_FLAG_DELETE_ON_CLOSE:文件关闭后自动删除。
FILE_FLAG_OVERLAPPED:启用异步 I/O。
7.hTemplateFile:HANDLE类型
指向模板文件的句柄。通常设置为 NULL,用的不是很多。
1. 创建新的空白文件
在D盘下创建一个"新年快乐.txt"文件,即读又写的权限,在使用时其他程序可以以读的权限打开,无其他特殊属性。
HANDLE handle1 = CreateFile(_T("D:\\新年快乐.txt"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (handle1 != INVALID_HANDLE_VALUE) // 函数执行成功{MessageBox(NULL, _T("文件成功创建"), _T("提示"), MB_OK);}else{MessageBox(NULL, _T("文件没有成功创建"), _T("提示"), MB_OK)}
运行后文件创建成功
D盘内也出现了该文件
2. 打开已存在文件
接下来使用CreateFile打开上述创建的文件
HANDLE handle1 = CreateFile(_T("D:\\新年快乐.txt"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (handle1 != INVALID_HANDLE_VALUE) // 函数执行成功{MessageBox(NULL, _T("文件成功打开"), _T("提示"), MB_OK);}else{MessageBox(NULL, _T("文件没有成功打开"), _T("提示"), MB_OK)}
运行后提示文件打开
如果我们将这个文件重命名,则D盘内不存在“新年快乐.txt”
此时运行则无法打开文件
利用GetLastError()函数可以看到错误码为2,即系统找不到指定文件。
GetLastError()的相关用法见GetLastError相关用法
3. 打开一个文件时,如果文件存在则打开,如果文件不存在则新创建文件
上述打开一个不存在的文件时,直接无法打开。这里实现打开一个不存在的文件时,创建该文件
HANDLE handle1 = CreateFile(_T("D:\\新年快乐.txt"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (handle1 != INVALID_HANDLE_VALUE) // 函数执行成功{MessageBox(NULL, _T("文件成功打开"), _T("提示"), MB_OK);}else{DWORD dwerror = GetLastError();MessageBox(NULL, _T("文件没有成功打开"), _T("提示"), MB_OK);}
可以看见新创建了一个“新年快乐.txt”
并将文件打开了
4.打开一个文件,如果文件存在则打开文件并清空内容,文件不存在则 新创建文件
然后,实现打开一个文件,如果文件存在则打开并清空内容,文件不存在则新创建文件
先在D盘中的“新年快乐.txt”中输入一些内容
代码只需要将上述的OPEN_ALWAYS换为CREATE_ALWAYS即可
运行后文件内容被清空了
二、关闭文件句柄CloseHandle
CloseHandle的函数原型如下,本质上是关闭刚刚利用CreateFile打开的文件的句柄。
BOOL CloseHandle(HANDLE hObject // 要关闭的句柄
);
CloseHandle函数关闭一个内核对象,其中包括文件、文件映射、线程、安全和同步对象等等。
在CreateThread成功之后会返回一个hThread的线程句柄,且内核对象计数+1,CloseHandle之后,引用计数-1,当变为0时,系统删除该内核对象。
若在线程执行之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露。这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出之后,系统会自动清理这些资源。
参数:HANDLE hObject代表一个已经打开的对象句柄,例如文件句柄、线程句柄、进程句柄等。
返回值:布尔类型,TRUE表示函数执行成功;FALSE表示函数执行失败,可以利用GetLastError获得错误码。
简单使用时按图示进行使用即可
总结
Windows 程序设计7:文件的创建、打开与关闭。