磁盘文件的正常读写与异步读写

在Win32系统下文件可以支持平常的同步读写和异步读写(但在Win9X下,Win32系统不支持磁盘文件的异步读写)。本节在后面部分将会介绍,最后一段内容将向大家讲解一下文件的。

在Win32系统中支持64位长度的文件,所以在很多文件操作函数中需要两个DWORD参数来表示文件长度,一个DWORD用来表示低32位,另一个用来表示高32位。

文件的读写进行在文件被正确打开后,但请确认在打开文件时设置了正确的读写标记。在Win32的文件操作中没有了以前类似与以前ANSI C中的fputs fgets fprintf fscanf等函数,只有类似于fread和fwrite的ReadFile和WriteFile函数。

ReadFile用于文件读,函数原型为:

BOOL ReadFile( HANDLE hFile, // handle to file LPVOID lpBuffer, // data buffer DWORD nNumberOfBytesToRead, // number of bytes to read LPDWORD lpNumberOfBytesRead, // number of bytes read LPOVERLAPPED lpOverlapped // overlapped buffer );

其中各项参数的含义为:

hFile:文件句柄,为CreateFile时返回的句柄

lpBuffer:保存读入的数据的指针

nNumberOfBytesToRead:指定需要读入的字节数

lpNumberOfBytesRead:返回实际读入的字节数

lpOverlapped:在文件异步读写时使用的数据,在同步读写中全部都设置为NULL,在Win9X中只支持对串口的异步操作。

如果返回值为FALSE并且读入的字节数也返回为0,则表示文件到达了末尾。

WriteFile用于文件写,函数原型为: BOOL WriteFile( HANDLE hFile, // handle to file LPCVOID lpBuffer, // data buffer DWORD nNumberOfBytesToWrite, // number of bytes to write LPDWORD lpNumberOfBytesWritten, // number of bytes written LPOVERLAPPED lpOverlapped // overlapped buffer );

参数的含义和ReadFile类似。

如果需要移动文件指针到相关位置(和文件读写不同,这个函数没有异步版本),使用

DWORD SetFilePointer( HANDLE hFile, // handle to file LONG lDistanceToMove, // bytes to move pointer PLONG lpDistanceToMoveHigh, // bytes to move pointer DWORD dwMoveMethod // starting point );

其中各项参数的含义为:

hFile:文件句柄,为CreateFile时返回的句柄

lpBuffer:保存读入的数据的指针

lDistanceToMove:移动的字节数低DWORD

lpDistanceToMoveHigh:移动的字节数高DWORD,为了支持64位(2的64次方字节)长度的大文件,而用来指定64字节的高32位,如果文件大小只需要32位就可以表示,则设置为NULL

ldwMoveMethod:移动方法,可以选择下面的值。
FILE_BEGIN 从文件开始处开始移动
FILE_CURRENT 从文件开始除开始移动
FILE_END 从文件末尾开始移动

函数返回值和参数lpDistanceToMoveHigh(当该参数不为NULL时)表明文件指针当前的位置(从文件头到当前的字节数),但当参数lpDistanceToMoveHigh为NULL时如果返回INVALID_SET_FILE_POINTER表明执行失败,当参数 lpDistanceToMoveHigh不为NULL时如果返回INVALID_SET_FILE_POINTER还需要判断GetLastError 的返回值是否不为NO_ERROR。下面是两种情况下判断错误。

//第一种情况 DWORD dwPtr = SetFilePointer (hFile, lDistance, NULL, FILE_BEGIN) ; if (dwPtr == INVALID_SET_FILE_POINTER) // Test for failure { // Obtain the error code. dwError = GetLastError() ; // 处理错误 // . . . } // End of error handler //第二种情况 dwPtrLow = SetFilePointer (hFile, lDistLow, & lDistHigh, FILE_BEGIN) ; // Test for failure if (dwPtrLow == INVALID_SET_FILE_POINTER && (dwError = GetLastError()) != NO_ERROR ) { // 处理错误 // . . . } // End of error handler

在Win32中没有提供得到文件当前指针位置的函数,但通过SetFilePointer也可以确定文件指针当前的位置。在MSDN中提供了两个宏来得到当前文件的指针位置:

//对32位长度的文件 #define GetFilePointer(hFile) SetFilePointer(hFile, 0, NULL, FILE_CURRENT) //对超过32位长度的文件 #define GetVLFilePointer(hFile, lpPositionHigh) / (*lpPositionHigh = 0, / SetFilePointer(hFile, 0, lpPositionHigh, FILE_CURRENT))

对了可以通过SetFilePointer来得到文件长度,方法就是从文件位结束处移动0字节,返回值就是文件的长度。

HANDLE hFile = CreateFile(...);//打开文件进行读 DWORD dwLen; dwLen = SetFilePointer (hFile, 0, NULL, FILE_END) ; CloseHandle( hFile ) ;

当然Win32中也提供了专门的函数来得到文件的大小

BOOL GetFileSizeEx( HANDLE hFile, // handle to file PLARGE_INTEGER lpFileSize // file size ); typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; }; LONGLONG QuadPart; } LARGE_INTEGER, *PLARGE_INTEGER;

其中lpFileSize是一个联合数据,用来表明文件的大小。

文件的异步读写主要是用在大文件的读写上,当使用异步读写时,ReadFile和WriteFile会马上返回,并在读写完成时通知应用程序。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzxpdf.html