直入主题吧,文件读写主要使用了 以下几个函数:
(如果要使用通用对话框,包含#include <commDlg.h>,打开文件和保存文件的通用对话框都需要包含这个文件)
1.打开文件
(1)GetOpenFileName(OPENFILENAME ofn);
创建统一打开文件的通用对话框,使用前需要对 OPENFILENAME 结构里的各项属性值设置完成。
其中特别重要的是lpstrFile,指定打开文件的路径的指针。另外,筛选器szFilter 有固定格式,参照手册按格式写就可以了。
返回值:如果用户指定了一个文件名,点击OK按钮,返回值为非零。由OPENFILENAME结构的IPstrFile成员指向的缓冲区含有全路径和用户指定的文件名。如果用户取消或关闭Open对话框或错误出现,返回值为零。
(2)CreateFile();
HANDLE CreateFile(
LPCTSTR lpFileName, //指向文件名的指针
DWORD dwDesiredAccess, //访问模式(写/读)
DWORD dwShareMode, //共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针
DWORD dwCreationDisposition, //如何创建
DWORD dwFlagsAndAttributes, //文件属性
HANDLE hTemplateFile //用于复制文件句柄
);
用于打开文件,上一个函数中ofn.lpstrFile获得了文件路径,可以作为这个函数的第一个参数,其他参数按需求设置,相关宏查手册。
返回一个句柄,需要获得这个句柄来对文件进行操作。
返回值:文件句柄,若错误返回INVALID_HANDLE_VALUE表示出错,会设置GetLastError。即使函数成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也会设为ERROR_ALREADY_EXISTS
有资料认为这个函数是创建一个内核对象派生下来的文件对象,这个函数也可以用于创建文件。
2.读写文件。
(1)获取文件大小
LONG GetFileSize(HANDLE FileHandle , DWORD* high);
返回文件大小,后一个参数是用于返回文件的高两位。(头两位)没有找到其他详细信息,貌似这个函数不是很常用。
(2)读取文件
BOOL ReadFile(
HANDLE hFile, //文件的句柄
LPVOID lpBuffer, //用于保存读入数据的一个缓冲区
DWORD nNumberOfBytesToRead, //要读入的字符数LPDWORD lpNumberOfBytesRead, //指向实际读取字节数的指针
LPOVERLAPPED lpOverlapped //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
);
使用具体方式:直接调用,第二个参数保存从文件读取的信息。一般要获取返回值判断是否成功。
(3)写入文件
BOOL WriteFile(
HANDLE hFile, // 文件句柄
LPCVOID lpBuffer, // 数据缓存区指针
DWORD nNumberOfBytesToWrite, // 你要写的字节数
LPDWORD lpNumberOfBytesWritten, // 用于保存实际写入字节数的存储区域的指针
LPOVERLAPPED lpOverlapped // OVERLAPPED结构体指针
);
功能说明: 从文件指针指向的位置开始将数据写入到一个文件中, 且支持同步和异步操作,
如果文件打开方式没有指明FILE_FLAG_OVERLAPPED的话,当程序调用成功时,它将实际写入文件的字节数保存到lpNumberOfBytesWriten指明的地址空间中
如果文件要交互使用的话,当函数调用完毕时要记得调整文件指针
参数说明: HANDLE hFile, 需要写入数据的文件指针,这个指针指向的文件必须是GENERIC_WRITE access 访问属性的文件
LPOVERLAPPED lpOverlapped OVERLAPPED结构体指针,如果文件是以FILE_FLAG_OVERLAPPED方式打开的话,那么这个指针就不能为NULL
返回值: 调用成功,返回非0调用不成功,返回为0
(4)读写完成后一定要记得释放文件句柄,调用CloseHandle();
BOOL CloseHandle(
HANDLE hObject
);
参数
hObject :代表一个已打开对象handle。
返回值
TRUE:执行成功;
FALSE:执行失败,可以调用GetLastError()获知失败原因。
该函数可以关闭一个 “内核”对象,其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。
3.保存文件
(1)BOOL GetSaveFileName(LPOPENFILENAME Ipofn);
调用通用保存对话框,获取保存文件名。返回非零表示获取了路径,反之没有获取。
同理使用前需要对lpofn进行初始化,重要的域为
ofn.hwndOwner = hwnd ; //文件句柄
ofn.lpstrFile = pstrFileName ; //文件名 (含路径)
ofn.lpstrFileTitle = pstrTitleName ; //指向接收选择的文件的文件名和扩展名的缓冲(不带路径信息)。这个成员可以是NULL。
ofn.Flags = OFN_OVERWRITEPROMPT ; //定以 保存文件的行为,OFN_OVERWRITEPROMPT 表示 有文件重名时提示用户是否覆盖。
(2)使用CreateFile();来创建一个内存文件对象。
得到句柄后使用WriteFile();写入文件。
完成后使用CloseHandle();释放该文件对象。