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. LayUI制作日历工作记录簿

    标题不知道该如何取,大概就是用Lay UI的Table,制作一个日历,在日历上可以添加每天的工作简记录.记录下LayUI Table的一些用法,一些值得探索的地方在于日历生成后,给周末加背景色,当天加 ...

  2. M_map(五)

    一.圆形区域的画图 1. clear all LATLIMS=[14 22]; LONLIMS=[108 118];%南海边界范围 m_proj('miller','lon',LONLIMS,'lat ...

  3. 安装 MySQL 过程记录

    最近安装 MySQL 时 遇到了许多问题,记录一下安装过程以及遇到的问题. 第一步:在官网上下载适合自己版本的 MySQL,我选择的是 Windows 64 位免安装版的:    官网地址:https ...

  4. Babel快速入门

    作者:姜瑞涛 Github仓库:https://github.com/jruit/babel-tutorial 博客:姜瑞涛的官方网站 原文链接:https://www.jiangruitao.com ...

  5. Python常用模块之模块的使用

      一 模块介绍 1.什么是模块? #常见的场景:一个模块就是一个包含了一组功能的python文件,比如spam.py,模块名为spam,可以通过import spam使用. #在python中,模块 ...

  6. Django之auth用户认证

    auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: authenticate()    提供 ...

  7. Python学习笔记:迭代器(Iterator)详解

    一.可迭代的对象(Iterable) 1.定义:可以直接用在循环的数据类型,如list,tuple,dict,set,str,还有generator(生成器), 和带yield的函数,这些直接可以用在 ...

  8. stm32:#ifndef/#define/#endif使用

    参考:https://blog.csdn.net/abc5382334/article/details/18052757/ 比如:存在a.h文件#include "c.h"而此时b ...

  9. Shiro 笔记

    功能 认证 授权 加密 session 管理 认证 Subject 是一个与系统交互的实体,可以是人,也可以是其他等 调用 SecurityUtils.getSubject()返回当前Subject, ...

  10. 躁!DJ 风格 Java 桌面音乐播放器

    本文适合有 Java 基础知识的人群,跟着本文可学习和运行 Java 版桌面 DJ 音乐播放器. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列 ...