The ReadFile function checks for the end-of-file condition (EOF) differently for synchronous and asynchronous read operations. When a synchronous read operation gets to the end of a file, ReadFile returns TRUE and sets the variable pointed to by the lpNumberOfBytesRead parameter to zero. An asynchronous read operation can encounter the end of a file during the initiating call to ReadFile or during subsequent asynchronous operations if the file pointer is programmatically advanced beyond the end of the file.

The following C++ example shows how to test for the end of a file during a synchronous read operation.

C++
  // Attempt a synchronous read operation.
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL); // Check for eof.
if (bResult && nBytesRead == 0)
{
// at the end of the file
}

The test for end-of-file during an asynchronous read operation is slightly more involved than for a similar synchronous read operation. The end-of-file indicator for asynchronous read operations is when GetOverlappedResult returns FALSE and GetLastError returns ERROR_HANDLE_EOF.

The following C++ example shows how to test for the end of file during an asynchronous read operation.

C++
#include <windows.h>
#include <tchar.h>
#include <stdio.h> #define BUF_SIZE (61) LPCTSTR ErrorMessage( DWORD error ) // Routine Description:
// Retrieve the system error message for the last-error code
{ LPVOID lpMsgBuf; FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL ); return((LPCTSTR)lpMsgBuf);
} void GoDoSomethingElse(void) // Routine Description:
// Placeholder to demo when async I/O might want to do
// other processing.
{
printf("Inside GoDoSomethingElse()\n");
} DWORD AsyncTestForEnd( HANDLE hEvent, HANDLE hFile ) // Routine Description:
// Demonstrate async ReadFile operations that can catch
// End-of-file conditions. Unless the operation completes
// synchronously or the file size happens to be an exact
// multiple of BUF_SIZE, this routine will eventually force
// an EOF condition on any file. // Parameters:
// hEvent - pre-made manual-reset event.
//
// hFile - pre-opened file handle, overlapped.
//
// inBuffer - the buffer to read in the data to.
//
// nBytesToRead - how much to read (usually the buffer size). // Return Value:
// Number of bytes read.
{
char inBuffer[BUF_SIZE];
DWORD nBytesToRead = BUF_SIZE;
DWORD dwBytesRead = 0;
DWORD dwFileSize = GetFileSize(hFile, NULL);
OVERLAPPED stOverlapped = {0}; DWORD dwError = 0;
LPCTSTR errMsg = NULL; BOOL bResult = FALSE;
BOOL bContinue = TRUE; // Set up overlapped structure event. Other members are already
// initialized to zero.
stOverlapped.hEvent = hEvent; // This is an intentionally brute-force loop to force the EOF trigger.
// A properly designed loop for this simple file read would use the
// GetFileSize API to regulate execution. However, the purpose here
// is to demonstrate how to trigger the EOF error and handle it. while(bContinue)
{
// Default to ending the loop.
bContinue = FALSE; // Attempt an asynchronous read operation.
bResult = ReadFile(hFile,
inBuffer,
nBytesToRead,
&dwBytesRead,
&stOverlapped); dwError = GetLastError(); // Check for a problem or pending operation.
if (!bResult)
{
switch (dwError)
{ case ERROR_HANDLE_EOF:
{
printf("\nReadFile returned FALSE and EOF condition, async EOF not triggered.\n");
break;
}
case ERROR_IO_PENDING:
{
BOOL bPending=TRUE; // Loop until the I/O is complete, that is: the overlapped
// event is signaled. while( bPending )
{
bPending = FALSE; // Pending asynchronous I/O, do something else
// and re-check overlapped structure.
printf("\nReadFile operation is pending\n"); // Do something else then come back to check.
GoDoSomethingElse(); // Check the result of the asynchronous read
// without waiting (forth parameter FALSE).
bResult = GetOverlappedResult(hFile,
&stOverlapped,
&dwBytesRead,
FALSE) ; if (!bResult)
{
switch (dwError = GetLastError())
{
case ERROR_HANDLE_EOF:
{
// Handle an end of file
printf("GetOverlappedResult found EOF\n");
break;
} case ERROR_IO_INCOMPLETE:
{
// Operation is still pending, allow while loop
// to loop again after printing a little progress.
printf("GetOverlappedResult I/O Incomplete\n");
bPending = TRUE;
bContinue = TRUE;
break;
} default:
{
// Decode any other errors codes.
errMsg = ErrorMessage(dwError);
_tprintf(TEXT("GetOverlappedResult failed (%d): %s\n"),
dwError, errMsg);
LocalFree((LPVOID)errMsg);
}
}
}
else
{
printf("ReadFile operation completed\n"); // Manual-reset event should be reset since it is now signaled.
ResetEvent(stOverlapped.hEvent);
}
}
break;
} default:
{
// Decode any other errors codes.
errMsg = ErrorMessage(dwError);
printf("ReadFile GLE unhandled (%d): %s\n", dwError, errMsg);
LocalFree((LPVOID)errMsg);
break;
}
}
}
else
{
// EOF demo did not trigger for the given file.
// Note that system caching may cause this condition on most files
// after the first read. CreateFile can be called using the
// FILE_FLAG_NOBUFFERING parameter but it would require reads are
// always aligned to the volume's sector boundary. This is beyond
// the scope of this example. See comments in the main() function. printf("ReadFile completed synchronously\n");
} // The following operation assumes the file is not extremely large, otherwise
// logic would need to be included to adequately account for very large
// files and manipulate the OffsetHigh member of the OVERLAPPED structure. stOverlapped.Offset += dwBytesRead;
if ( stOverlapped.Offset < dwFileSize )
bContinue = TRUE;
} return stOverlapped.Offset;
} void __cdecl _tmain(int argc, TCHAR *argv[]) // To force an EOF condition, execute this application specifying a
// zero-length file. This is because the offset (file pointer) must be
// at or beyond the end-of-file marker when ReadFile is called. For
// more information, see the comments for the AsyncTestForEnd routine. {
HANDLE hEvent;
HANDLE hFile;
DWORD dwReturnValue; printf("\n");
if( argc != 2 )
{
printf("ERROR:\tIncorrect number of arguments\n\n");
printf("%s <file_name>\n", argv[0]);
return;
} hFile = CreateFile(argv[1], // file to open
GENERIC_READ, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_FLAG_OVERLAPPED, // overlapped operation
NULL); // no attr. template if (hFile == INVALID_HANDLE_VALUE)
{
DWORD dwError = GetLastError();
LPCTSTR errMsg = ErrorMessage(dwError);
printf("Could not open file (%d): %s\n", dwError, errMsg);
LocalFree((LPVOID)errMsg);
return;
} hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (hEvent == NULL)
{
DWORD dwError = GetLastError();
LPCTSTR errMsg = ErrorMessage(dwError);
printf("Could not CreateEvent: %d %s\n", dwError, errMsg);
LocalFree((LPVOID)errMsg);
return;
} dwReturnValue = AsyncTestForEnd(hEvent, hFile); printf( "\nRead complete. Bytes read: %d\n", dwReturnValue); CloseHandle(hFile);
CloseHandle(hEvent);
}

The output from this sample code is as follows.

syntax
ReadFile operation is pending
Inside GoDoSomethingElse()
GetOverlappedResult I/O Incomplete ReadFile operation is pending
Inside GoDoSomethingElse()
ReadFile operation completed Complete. Bytes read: 541

Testing for the End of a File (Windows 的异步 IO)的更多相关文章

  1. File类与常用IO流第四章——IO字节流

    一切文件在存储时,都是以二进制数字的形式保存的,都是一个一个字节.无论使用什么样的流对象,底层传输的始终是二进制数据. 字节输出流 OutputStream java.io.OutputStream ...

  2. 详解C#中System.IO.File类和System.IO.FileInfo类的用法

    System.IO.File类和System.IO.FileInfo类主要提供有关文件的各种操作,在使用时需要引用System.IO命名空间.下面通过程序实例来介绍其主要属性和方法. (1) 文件打开 ...

  3. oracle启用异步IO(db file async I/O submit)

    市局双随机awr报告中有大量db file async I/O submit等待事件 参考两篇文章: [案例]Oracle等待事件db file async I/O submit产生原因和解决办法 d ...

  4. 在Windows中监视IO性能

    附:在Windows中监视IO性能 本来准备写一篇windows中监视IO性能的,后来发现好像可写的内容不多,windows在细节这方面做的不是那么的好,不过那些基本信息还是有的. 在Windows中 ...

  5. Windows五种IO模型性能分析和Linux五种IO模型性能分析

    Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...

  6. windows下的IO模型之异步选择(WSAAsyncSelect)模型

    异步选择(WSAAsyncSelect)模型是一个有用的异步I/O 模型.其核心函数是WSAAsyncSelect,该函数是非阻塞的 (关于异步io的理解详情可以看:http://www.cnblog ...

  7. Windows 异步IO操作

    Windows提供了4种不同的方法来接收I/O请求已经完成的通知:触发设备内核对象.触发事件内核对象.可提醒I/O和I/O完成端口. Windows的异步I/O     当线程向设备发起一个I/O异步 ...

  8. 《Windows核心编程系列》十谈谈同步设备IO与异步设备IO之异步IO

    同步设备IO与异步设备IO之异步IO介绍 设备IO与cpu速度甚至是内存访问相比较都是比较慢的,而且更不可预测.虽然如此,通过使用异步设备IO我们仍然能够创造出更高效的程序. 同步IO时,发出IO请求 ...

  9. Smobiler与Windows的异步回调差别

    Smobiler与Windows的异步回调差别--基于.NET的APP开发和Windows开发差别 基于.NET的APP开发和Windows开发,异步回调差别 Windows app开发 异步回调 S ...

随机推荐

  1. [转载]Docker容器无法被stop or kill问题

    来源: 问题过程 某环境一个mysql容器无法被stop or kill or rm sudo docker ps | grep mysql 查看该容器 7844250860f8 mysql:5.7. ...

  2. Python Count函数的应用

    Python Count函数的应用 通过LeetCode Origin:https://leetcode-cn.com/problems/robot-return-to-origin/ 学会了Pyth ...

  3. K:leetcode 5381.查询带键的排列 这题简单,但我还能优化。精益求精,才是算法的乐趣所在!

    前言: 本题来自leetcode第184场周赛的第二小题.以前参加过周赛,觉得很有趣.苦于最近一段时间比较忙就没坚持参加了(实际上是借口来着....),由于昨晚思考一些事情,导致睡不着,所以起得有点早 ...

  4. 家庭版记账本app开发之关于(数据库查找出数据)圆饼图的生成

    这次完成的主要的怎样从数据库中调出数据.之后通过相关的数据,生成想要的圆饼图.以方便用户更加直观的看见关于账本的基本情况. 在圆饼图生成中用到了一些外部资源 具体的import如下: import c ...

  5. linux系统管理,查看系统资源

    free 查看内存使用情况 -b  ===>  以byte为单位 -k  ===>  以Kb为单位 -m  ===>  以Mb为单位 -g  ===>  以Gb为单位 -t  ...

  6. HAproxy 基础配置

    基础配置详解 HAProxy 的配置文件haproxy.cfg由两大部分组成,分别是global和proxies部分 global:全局配置段 进程及安全配置相关的参数性能调整相关参数Debug参数 ...

  7. Apache Hudi 设计与架构最强解读

    感谢 Apache Hudi contributor:王祥虎 翻译&供稿. 欢迎关注微信公众号:ApacheHudi 本文将介绍Apache Hudi的基本概念.设计以及总体基础架构. 1.简 ...

  8. Git应用详解第六讲:Git协作与Git pull常见问题

    前言 前情提要:Git应用详解第五讲:远程仓库Github与Git图形化界面 git除了可以很好地管理个人项目外,最大的一个用处就是实现团队协作开发.况且,linus大神开发git的初衷就是为了维护L ...

  9. std::string 字符串分割

    #include <iostream> #include <string> #include <vector> std::vector<std::string ...

  10. jmeter 信息头Bearer

    1.数据规则 2.登录时获取token信息 3.正则表达式获取token值 说明: (1)引用名称:下一个请求要引用的参数名称,如填写title,则可用${title}引用它. (2)正则表达式: ( ...