ReadFile

来源:互联网 发布:js 3D图形插件 编辑:程序博客网 时间:2024/05/16 07:10

ReadFile函数从文件指针指定的位置读取数据。读操作完成后,文件指针将根据实际读出的数据自动进行调整,除非文件句柄是以OVERLAPPED属性值打开的。如果是以OVERLAPPED打开的I/O,应用程序就需要自己手动调整文件指针。
    这个函数被设计成兼有同步和异步操作。ReadFileEx函数则设计成只支持异步操作,异步操作允许应用程序在读文件期间可以同时进行其他的操作。
    函数原型:
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
);

【Parameters】
1、hFile
    文件句柄(必须具有GENERIC_READ访问权限)。
    在Windows NT/2000/XP平台上:对于异步读操作,hFile可以是由CreateFile函数以FILE_FLAG_OVERLAPPED方式打开的任何句柄,或者一个由socket或accept函数返回的socket句柄。
    在Windows 95/98/Me平台上:对于邮槽、命名管道和磁盘文件不能使用异步读操作。
2、lpBuffer
    用来接收从文件中读出的数据的缓冲区指针。
3、nNumberOfBytesToRead
    指明要读的字节总数。
4、lpNumberOfBytesRead
    一个变量指针,用来存储实际传输的字节总数。ReadFile在做所有事情(包括错误检查)之前,先将这个值赋为0。当ReadFile从一个命名管道上返回TRUE时这个参数为0,说明消息管道另一端调用WriteFile时设置的nNumberOfBytesToWrite 参数为0。
    在Windows NT/2000/XP平台上:如果lpOverlapped 为NULL,则lpNumberOfBytesRead不能为NULL。如果lpOverlapped 不是NULL,lpNumberOfBytesRead可以设为NULL。如果是一个overlapped形式的读操作,我们可以动用GetOverlappedResult函数来获得传输的实际字节数。如果hFile关联的是一个完成端口(I/O completion port),那么可以调用GetQueuedCompletionStatus函数来获得传输的实际字节数。
    如果完成端口(I/O completion port)被占用,而你用的是一个用于释放内存的回调例程,对于lpOverlapped参数指向的OVERLAPPED结构体来说,为这个参数指定NULL可以避免重新分配内存时发生内存泄漏。内存泄漏会导致返回这个参数值时是一个非法值。
    Windows 95/98/Me平台上:这个参数不允许为NULL。
5、lpOverlapped
    一个指向OVERLAPPED结构体的指针。如果hFile是以FILE_FLAG_OVERLAPPED方式获得的句柄,这个结构是必须的,不能为NULL。(否则函数会在错误的时刻报告读操作已经完成了)。这时,读操作在由OVERLAPPED中Offset成员指定的偏移地址开始读,并且在实际完成读操作之前就返回了。在这种情况下,ReadFile返回FALSE,GerLastError报告从错误类型是ERROR_IO_PENDING。这允许调用进程继续其他工作直到读操作完成。OVERLAPPED结构中的事件将会在读操作完成时被使能。
    如果hFile不是以FILE_FLAG_OVERLAPPED方式获得的句柄,并且lpOverlapped为NULL,读操作就从当前文件的开始位置读起,直到读操作完成ReadFile函数才能返回。
    在Windows NT/2000/XP平台上:如果hFile不是以FILE_FLAG_OVERLAPPED方式获得的句柄,并且lpOverlapped不为NULL,则读操作在由OVERLAPPED中Offset成员指定的偏移地址开始读,直到读操作完成ReadFile函数才能返回。
    在Windows 95/98/Me平台上:对于文件、磁盘、管道和邮槽的操作,这个参数必须为NULL。一个不为空的OVERLAPPED结构体指针将导致调用失败。Windows 95/98/Me平台只支持串行口和并行口的overlapped 读写。

【Return Values】
    有如下任一种情况发生都会导致函数返回:(1)在管道另一端的写操作完成后(2)请求的字节数传输完毕(3)发生错误。
    如果函数正确,返回非零。
    如果返回值是非零,但接收的字节数是0,那么可能是文件指针在读操作期间超出了文件的end位置。然而,如果文件以FILE_FLAG_OVERLAPPED方式打开,lpOverlapped 参数不为NULL,文件指针在读操作期间超出了文件的end位置,那么返回值肯定是FALSE,GetLastError返回的错误是ERROR_HANDLE_EOF。

【Remarks】
    如果文件的一部分被另一个进程锁定,而当前进程试图重复锁定,那将会失败。
    一个应用程序在读以FILE_FLAG_NO_BUFFERING方式打开的文件时要符合一定的条件。
(1)文件读的开始地址必须是扇区大小的整数倍。GetDiskFreeSpace函数可以取得扇区的大小。
(2)请求读的字节数也必须是扇区大小的整数倍。
(3)用于读写操作的Buffer地址必须按照扇区大小进行边界对齐。可以通过用VirtualAlloc 函数申请内存来做到。
    在读操作期间试图访问相应的输入缓冲区,会导致读入到缓冲区的数据损坏。读操作完成之前,应用程序不能对这段输入缓冲区做任何操作(包括读、写、重新分配内存,释放内存等)。
    ReadFile可以通过指向控制台输入对象的句柄将控制台的输入字符读出来。控制台的模式决定了ReadFile的具体行为。
    如果一个命名管道正在以消息模式被读取,并且下一条消息比nNumberOfBytesToRead参数指定的长度还大,那么ReadFile将返回FALSE并且GetLastError返回错误为ERROR_MORE_DATA。剩下没读完的消息可能会被随后的ReadFile或PeckNamedPipe函数读出。
    读取一个通信设备时,ReadFile的行为被当前的通信延时所支配,延时属性的设置和取得使用SetCommTimeouts和GetCommTimeouts函数。如果你设置延时属性失败,就会得到不可预知的结果。
    如果ReadFile试图读取一个buffer太小的邮槽,将会返回FALSE并且GetLastError返回错误为ERROR_INSUFFICIENT_BUFFER 。
    如果一个匿名的写管道句柄已经关闭,而ReadFile试图用响应的匿名权限读这个管道句柄,将返回FALSE并且
GetLastError返回错误为ERROR_BROKEN_PIPE。
    每当有太多的异步I/O请求得不到响应,ReadFile就会失败,并返回ERROR_INVALID_USER_BUFFER或ERROR_NOT_ENOUGH_MEMORY的错误。
    在同步和异步两种情况下,ReadFile中检测EOF(文件结尾边界)的代码是不同的。当一个同步读操作到达文件结尾时,ReadFile返回TRUE,并设置*lpNumberOfBytesRead 为0 。异步读操作会在开始调用的读操作中或者随后的其他异步操作中突然遇到文件结尾。(1)如果EOF在ReadFile期间被检测到,将会返回FALSE,且 GetLastError返回错误描述 ERROR_HANDLE_EOF。(2)如果EOF在随后的其他异步操作中被检测到,则类似GetOverlappedResult 等试图获取操作结果的函数返回FALSE,且 GetLastError返回错误描述ERROR_HANDLE_EOF。
    为了取消未响应的异步I/O操作,用CancelIo函数。这个函数只能取消由调用进程对特定句柄进行的操作。被取消的I/O操作将被描述为ERROR_OPERATION_ABORTED。
    如果你正试图从并不存在的软驱中读数据,系统会弹出消息框提示你重新操作。为了阻止系统的消息框,调用函数SetErrorMode,参数设置为SEM_NOOPENFILEERRORBOX。

参考来源:http://blog.csdn.net/kampan/archive/2008/07/31/2744400.aspx
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 幼儿园小孩数字记不住怎么办 大班教案走丢了怎么办 ppt加视频反了怎么办 拔罐之后背疼怎么办 拔完火罐后背疼怎么办 打印机红色的口堵了怎么办 打印机红色复印不出来怎么办 打印机加错颜色墨水怎么办 中班安全教案脚扭伤了怎么办 中班脚扭伤了怎么办教案 中班安全脚扭伤了怎么办 中班安全脚扭伤了怎么办反思 走丢了怎么办教案反思 汽车后轱辘不转怎么办 走丢了怎么办社会教案 小老鼠搬鸡蛋鸡蛋太大怎么办 小班走丢了怎么办教案 小班走丢了怎么办反思 房屋外墙漏水物业不管怎么办 厨房墙砖用色花怎么办 小孩子做错事很偏激怎么办 孩子在学校偷钱怎么办 房间墙壁上到处有湿虫怎么办 买了西晒的房子怎么办 墙面瓷砖下水管漏水怎么办 西晒房间开空调没效果怎么办 墙纸被小孩画了怎么办 集成墙板缝隙大怎么办 高血压变低血压怎么办会恢复吗 总是感觉睡不够好困怎么办 两岁宝宝说有鬼怎么办 阳台改成了卧室晒衣服怎么办 室外墙角边墙泥受潮脱落怎么办 新房装修墙体发霉了怎么办 宝宝吃多了发烧怎么办 宝宝睡觉不爱盖被子怎么办 1岁宝宝不盖被子怎么办 2岁宝宝不盖被子怎么办 买的芬琳漆不够刷的怎么办 1.3米宽厨房门怎么办 墙面漆颜色刷深了怎么办