C语言文件操作:CreateFile与fopen对比及示例
本文介绍了C语言中两种核心文件操作方式:使用Windows API的CreateFile进行底层句柄控制,以及使用C标准库的fopen进行流式数据读写。通过具体代码示例,详细解析了打开文件、写入缓冲区、同步缓存、重置指针及关闭资源的标准流程,帮助开发者根据性能需求选择合适方案。
Windows API方式:CreateFile底层操作
CreateFile是Windows系统中用于创建或打开文件的底层API,它返回一个文件句柄(HANDLE)。这种方式提供了更细粒度的控制,适合需要精确管理文件属性、权限或进行高性能IO的场景。以下是一个完整的操作流程,包括打开、获取大小、写入、同步、读取和关闭。
第1步:初始化头文件并定义主函数入口
首先包含必要的头文件。stdafx.h通常用于预编译头,windows.h提供Windows API支持。在控制台程序启动时,进入main函数。
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
void main(int argc, char* argv[])
{
// ... 后续步骤
}
第2步:打开文件并验证句柄有效性
调用CreateFile打开指定路径的文件。参数说明如下:
- lpFileName: 文件路径,如
C:\S.txt。 - dwDesiredAccess: 访问权限,此处使用
GENERIC_READ|GENERIC_WRITE同时支持读写。 - dwShareMode: 共享模式,设为
0表示独占访问。 - lpSecurityAttributes: 安全属性,设为
NULL使用默认设置。 - dwCreationDisposition: 创建行为,此处使用
OPEN_EXISTING,要求文件必须存在。 - dwFlagsAndAttributes: 文件属性,
FILE_ATTRIBUTE_NORMAL表示普通文件。 - hTemplateFile: 模板文件句柄,设为
NULL。
操作完成后,必须检查返回值是否等于 INVALID_HANDLE_VALUE。若相等,则通过 GetLastError() 获取错误码并提示失败。
HANDLE hDevice = CreateFile("C:\\S.txt",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("Failed to obtain file with %d error code !\n", GetLastError());
return;
}
第3步:获取文件大小(可选)
使用 GetFileSize 函数获取文件当前长度,单位为字节。第二个参数指向 DWORD 变量以接收高32位值,若只需低32位可传入 NULL。
DWORD dwSize = GetFileSize(hDevice, NULL);
printf("File size: %d bytes\n", dwSize);
第4步:准备缓冲区并执行写入操作
定义字符数组作为写入缓冲区。调用 WriteFile 将数据写入文件。注意:WriteFile 不会自动将数据刷入磁盘存储介质,需配合后续同步操作。
- hFile: 文件句柄。
- lpBuffer: 要写入的数据缓冲区。
- nNumberOfBytesToWrite: 要写入的字节数。
- lpNumberOfBytesWritten: 实际写入字节数的输出变量。
char chBuffer[10] = "5469";
DWORD dwWriteSize = 0;
BOOL bRet = WriteFile(hDevice, chBuffer, 4, &dwWriteSize, NULL);
if(bRet)
{
printf("Write success. Bytes written: %d\n", dwWriteSize);
}
else
{
printf("Write failed with error code: %d\n", GetLastError());
}
第5步:同步文件缓冲区到磁盘
为了确保刚才写入的数据物理上保存到硬盘,避免系统崩溃或断电导致数据丢失,必须调用 FlushFileBuffers。这是一个耗时操作,但在关键数据存储时必不可少。
FlushFileBuffers(hDevice);
第6步:重置文件指针并执行读取
由于之前进行了写入,文件指针可能位于文件末尾。为了从头读取,使用 SetFilePointer 将指针移回文件开头(FILE_BEGIN)。
接着调用 ReadFile 从文件中读取数据到 chBuffer。注意读取缓冲区的大小应大于或等于预期读取的字节数。
LONG lDistance = 0;
// 将文件指针移动到文件开头
DWORD dwPtr = SetFilePointer(hDevice, lDistance, NULL, FILE_BEGIN);
DWORD dwReadSize = 0;
// 重置缓冲区以防残留
memset(chBuffer, 0, sizeof(chBuffer));
bRet = ReadFile(hDevice, chBuffer, 10, &dwReadSize, NULL);
if (bRet && dwReadSize > 0)
{
printf("Read content: %s\n", chBuffer);
}
else
{
printf("Read failed or no data.");
}
第7步:关闭文件句柄
操作结束后,务必调用 CloseHandle 释放资源,否则会导致句柄泄露。
CloseHandle(hDevice);
return ;
}
C标准库方式:fopen流式文件操作
相比于CreateFile,C标准库提供的fopen更为简洁,适用于跨平台应用或不需要复杂文件属性的常规读写任务。它基于文件指针(FILE*)进行管理,抽象了底层的硬件交互。
第1步:声明文件指针并打开文件
使用FILE*类型声明指针。调用fopen打开文件,第一个参数为路径,第二个参数为模式字符串。常用模式包括"r"(只读)、"w"(只写,清空原文件)、"rb"(二进制只读)、"wb"(二进制只写)等。本例中使用"rb"以二进制模式打开,常用于处理非文本文件或确保兼容性。
FILE *fp_sys;
fp_sys = fopen("data.bin", "rb"); // 假设打开一个二进制文件
if(fp_sys == NULL) {
// 打开失败处理,可根据环境使用printf或日志记录
fprintf(stderr, "Unable to open file\n");
exit(1);
}
第2步:执行文件I/O操作
打开成功后,可使用fread、fwrite、fscanf等函数进行操作。例如,读取缓冲区数据:
char datain[101];
size_t items_read = fread(datain, 1, sizeof(datain), fp_sys);
if(items_read > 0) {
// 处理读取到的数据
printf("Read %zu bytes\n", items_read);
}
第3步:关闭文件
同样地,操作完成后需调用fclose释放关联的资源缓冲区并关闭文件描述符。
fclose(fp_sys);
总结与建议
CreateFile适用于Windows环境下对文件系统有高精度控制需求的场景,如异步IO、内存映射文件或特殊权限管理;而fopen因其简单性和跨平台特性,更适合通用应用程序的快速开发。在实际工程中,应根据目标平台和性能要求选择合适的文件操作接口。
以上就是C语言文件操作方法CreateFile和fopen的详细内容,更多关于C++文件读写技巧的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













