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. XDebug的配置和使用

    简介 XDebug是一个开放源代码的PHP程序调试器(即一个Debug工具) 可以用来跟踪,调试和分析PHP程序的运行状况 功能强大的神器,对审计有非常大的帮助. 官网:http://www.xdeb ...

  2. 使用 nodejs 对文件进行批量重命名

    0. 前言 从B站下载了一点视频,硕鼠自动将标题添加到了每个文件名的前面,导致文件名过长,不方面查看文件的具体内容. 虽然只有二十几个文件,但是手动删除前缀还是个不小的工作量,还有可能删除错误.考虑到 ...

  3. IDEA+EasyCode实现代码生成

    IDEA+EasyCode实现代码生成 Easy Code介绍 EasyCode是基于IntelliJ IDEA开发的代码生成插件,支持自定义任意模板(Java,html,js,xml).只要是与数据 ...

  4. Java 为 Excel 中的行设置交替背景色

    在制作Excel表格时,通过将数据表中上下相邻的两行用不同的背景色填充,可以使各行的数据看起来更清楚,避免看错行,同时也能增加Excel表格的美观度.本文将介绍如何在Java程序中为 Excel 奇数 ...

  5. php simplexml_load_string 返回的对象print_r后,丢失信息?

    <?php $content = '<dblp> <inproceedings key="conf/aaim/He07" mdate="2007- ...

  6. PHP获取当天、本周、本月、本季度、本年度时间

    function get_date($date, $t = 'd', $n = 0) { if ($t == 'd') { $firstday = date('Y-m-d 00:00:00', str ...

  7. matplotlib中的基本概念

    有外语基础的朋友看这里: matplotlib官方文档 Figure(图像): 组成部分

  8. .Net Core结合AspNetCoreRateLimit实现限流

    前言 相信使用过WebApiThrottle的童鞋对AspNetCoreRateLimit应该不陌生,AspNetCoreRateLimit是一个ASP.NET Core速率限制的解决方案,旨在控制客 ...

  9. cxx signal信号捕获

    kill -9 [pid] 该信号不能被捕获 #include <iostream> #include <csignal> static void vSignalHandler ...

  10. intellJ svn控制错误

    电脑突然蓝屏了,重启打开intellj 后原本好好的项目是可以用intellj更新或者提交的,现在却都不能了,如图: 如上图:svn地址里是空白的,应该显示: 那到底是什么情况呢,就因为电脑崩溃了in ...