1、创建文件
在 Windows 编程中,CreateFile()
是一个 Windows API 函数,用于创建或打开一个文件、文件夹、通信资源、磁盘分区等。这个函数提供了比标准 C++ 文件操作更详细的控制,包括安全属性、文件共享模式、文件创建方式等。
函数原型
HANDLE CreateFile(
LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
参数说明
- lpFileName: 要创建或打开的文件名。
- dwDesiredAccess: 访问文件的方式,如读 (
GENERIC_READ
)、写 (GENERIC_WRITE
) 或两者 (GENERIC_READ | GENERIC_WRITE
)。 - dwShareMode: 文件共享模式,如共享读 (
FILE_SHARE_READ
)、共享写 (FILE_SHARE_WRITE
)。 - lpSecurityAttributes: 指向
SECURITY_ATTRIBUTES
结构的指针,可以为NULL
。 - dwCreationDisposition: 控制如何创建或打开文件,如
CREATE_NEW
,CREATE_ALWAYS
,OPEN_EXISTING
,OPEN_ALWAYS
,TRUNCATE_EXISTING
。 - dwFlagsAndAttributes: 文件或设备的属性,如
FILE_ATTRIBUTE_NORMAL
。 - hTemplateFile: 用于复制文件属性的模板文件的句柄,通常设置为
NULL
。
返回值
如果函数成功,返回值是新创建或打开的文件的句柄。如果函数失败,返回值是 INVALID_HANDLE_VALUE
。可以调用 GetLastError()
函数来获取更多错误信息。
示例代码
#include <windows.h>
#include <iostream>
int main() {
// 创建或打开文件
HANDLE hFile = CreateFile(
"example.txt", // 文件名
GENERIC_READ | GENERIC_WRITE, // 读写访问
0, // 不共享文件
NULL, // 默认安全属性
CREATE_NEW, // 创建新文件,如果文件存在则失败
FILE_ATTRIBUTE_NORMAL, // 普通文件属性
NULL // 没有模板文件
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to create or open file. Error: " << GetLastError() << std::endl;
return 1;
}
std::cout << "File created or opened successfully." << std::endl;
// 关闭文件句柄
CloseHandle(hFile);
return 0;
}
在这个示例中,我们尝试创建一个新文件 “example.txt”。如果文件已存在,CreateFile()
将失败。我们检查返回的句柄是否有效,以确定操作是否成功,并在完成后关闭句柄。
注意事项
- 使用
CreateFile()
时应确保正确处理安全权限和文件共享模式,以避免安全漏洞或资源冲突。 - 在操作完成后,应使用
CloseHandle()
函数关闭文件句柄,以释放系统资源。
2、写文件
在 Windows 编程中,WriteFile()
是一个 Windows API 函数,用于将数据写入文件或 I/O 设备。这个函数是与 CreateFile()
配合使用的,用于文件写操作。
函数原型
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
参数说明
- hFile: 通过
CreateFile()
打开的文件或设备的句柄。 - lpBuffer: 指向包含要写入文件的数据的缓冲区的指针。
- nNumberOfBytesToWrite: 要写入的字节数。
- lpNumberOfBytesWritten: 实际写入的字节数的指针,该参数可以为
NULL
。 - lpOverlapped: 指向
OVERLAPPED
结构的指针,用于异步操作,对于同步操作,此参数应为NULL
。
返回值
如果函数成功,返回值为非零(TRUE)。如果函数失败,返回值为零(FALSE)。可以调用 GetLastError()
函数来获取更多错误信息。
示例代码
#include <windows.h>
#include <iostream>
int main() {
// 打开文件
HANDLE hFile = CreateFile(
"example.txt", // 文件名
GENERIC_WRITE, // 写访问
0, // 不共享文件
NULL, // 默认安全属性
OPEN_EXISTING, // 打开现有文件
FILE_ATTRIBUTE_NORMAL, // 普通文件属性
NULL // 没有模板文件
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open file. Error: " << GetLastError() << std::endl;
return 1;
}
// 要写入的数据
const char* data = "Hello, world!";
DWORD bytesWritten;
// 写入文件
BOOL result = WriteFile(
hFile, // 文件句柄
data, // 数据缓冲区
strlen(data), // 要写入的字节数
&bytesWritten, // 实际写入的字节数
NULL // 不使用 OVERLAPPED 结构
);
if (!result) {
std::cerr << "Failed to write to file. Error: " << GetLastError() << std::endl;
CloseHandle(hFile);
return 1;
}
std::cout << "Wrote " << bytesWritten << " bytes to file successfully." << std::endl;
// 关闭文件句柄
CloseHandle(hFile);
return 0;
}
在这个示例中,我们首先打开一个现有的文件 “example.txt”,然后写入字符串 “Hello, world!”。我们检查 WriteFile()
的返回值以确定写入操作是否成功,并在完成后关闭文件句柄。
注意事项
- 确保在调用
WriteFile()
之前正确打开文件,并具有适当的写权限。 - 如果使用异步操作,需要正确处理
OVERLAPPED
结构。 - 在操作完成后,应使用
CloseHandle()
函数关闭文件句柄,以释放系统资源。
3、读文件
在 Windows 编程中,ReadFile()
是一个 Windows API 函数,用于从文件或输入/输出 (I/O) 设备读取数据。这个函数通常与 CreateFile()
配合使用,用于文件读操作。
函数原型
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
参数说明
- hFile: 通过
CreateFile()
打开的文件或设备的句柄。 - lpBuffer: 指向缓冲区的指针,该缓冲区将接收从文件或设备读取的数据。
- nNumberOfBytesToRead: 要从文件或设备读取的字节数。
- lpNumberOfBytesRead: 指向变量的指针,该变量接收实际读取的字节数。这个参数可以为
NULL
如果lpOverlapped
不是NULL
。 - lpOverlapped: 指向
OVERLAPPED
结构的指针,用于异步操作。对于同步操作,此参数应为NULL
。
返回值
如果函数成功,返回值为非零(TRUE)。如果函数失败,返回值为零(FALSE)。可以调用 GetLastError()
函数来获取更多错误信息。
示例代码
#include <windows.h>
#include <iostream>
int main() {
// 打开文件
HANDLE hFile = CreateFile(
"example.txt", // 文件名
GENERIC_READ, // 读访问
FILE_SHARE_READ, // 共享读
NULL, // 默认安全属性
OPEN_EXISTING, // 打开现有文件
FILE_ATTRIBUTE_NORMAL, // 普通文件属性
NULL // 没有模板文件
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open file. Error: " << GetLastError() << std::endl;
return 1;
}
char buffer[128]; // 数据缓冲区
DWORD bytesRead; // 读取的字节数
// 读取文件
BOOL result = ReadFile(
hFile, // 文件句柄
buffer, // 数据缓冲区
sizeof(buffer), // 要读取的字节数
&bytesRead, // 实际读取的字节数
NULL // 同步操作
);
if (!result) {
std::cerr << "Failed to read file. Error: " << GetLastError() << std::endl;
CloseHandle(hFile);
return 1;
}
std::cout << "Read " << bytesRead << " bytes from file." << std::endl;
std::cout.write(buffer, bytesRead);
// 关闭文件句柄
CloseHandle(hFile);
return 0;
}
在这个示例中,我们首先使用 CreateFile()
打开一个文件,然后使用 ReadFile()
从文件中读取数据。读取的数据被存储在一个字符数组 buffer
中,并且实际读取的字节数被存储在 bytesRead
中。最后,我们输出读取的数据并关闭文件句柄。
注意事项
- 确保为
lpBuffer
提供足够大的缓冲区以接收预期的数据。 - 在操作完成后,应使用
CloseHandle()
函数关闭文件句柄,以释放系统资源。 - 对于异步操作,需要正确处理
OVERLAPPED
结构和相关的完成例程或事件对象。
4、实际操作
void CFileProjDlg::OnBnClickedButtonWrite()
{
//win32 API
//创建文件
HANDLE hFile;
hFile = CreateFile("3.txt", GENERIC_WRITE, NULL,NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
MessageBox("创建文件失败!");
return;
}
//写文件
DWORD dwWrite;
char szBuf[1024] = "WIN API 操作文件";
WriteFile(hFile, szBuf, strlen(szBuf), &dwWrite, NULL);
CloseHandle(hFile);
}
void CFileProjDlg::OnBnClickedButtonRead()
{
//win32 API
//创建文件
HANDLE hFile;
hFile = CreateFile("3.txt", GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
MessageBox("创建文件失败!");
return;
}
//读文件
DWORD dwRead;
char szBuf[1024] = { 0 };
ReadFile(hFile, szBuf, 1024, &dwRead, NULL);
CloseHandle(hFile);
MessageBox(szBuf);
}