Testing for the End of a File (Windows 的异步 IO)
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.
// 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.
#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.
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)的更多相关文章
- File类与常用IO流第四章——IO字节流
一切文件在存储时,都是以二进制数字的形式保存的,都是一个一个字节.无论使用什么样的流对象,底层传输的始终是二进制数据. 字节输出流 OutputStream java.io.OutputStream ...
- 详解C#中System.IO.File类和System.IO.FileInfo类的用法
System.IO.File类和System.IO.FileInfo类主要提供有关文件的各种操作,在使用时需要引用System.IO命名空间.下面通过程序实例来介绍其主要属性和方法. (1) 文件打开 ...
- oracle启用异步IO(db file async I/O submit)
市局双随机awr报告中有大量db file async I/O submit等待事件 参考两篇文章: [案例]Oracle等待事件db file async I/O submit产生原因和解决办法 d ...
- 在Windows中监视IO性能
附:在Windows中监视IO性能 本来准备写一篇windows中监视IO性能的,后来发现好像可写的内容不多,windows在细节这方面做的不是那么的好,不过那些基本信息还是有的. 在Windows中 ...
- Windows五种IO模型性能分析和Linux五种IO模型性能分析
Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...
- windows下的IO模型之异步选择(WSAAsyncSelect)模型
异步选择(WSAAsyncSelect)模型是一个有用的异步I/O 模型.其核心函数是WSAAsyncSelect,该函数是非阻塞的 (关于异步io的理解详情可以看:http://www.cnblog ...
- Windows 异步IO操作
Windows提供了4种不同的方法来接收I/O请求已经完成的通知:触发设备内核对象.触发事件内核对象.可提醒I/O和I/O完成端口. Windows的异步I/O 当线程向设备发起一个I/O异步 ...
- 《Windows核心编程系列》十谈谈同步设备IO与异步设备IO之异步IO
同步设备IO与异步设备IO之异步IO介绍 设备IO与cpu速度甚至是内存访问相比较都是比较慢的,而且更不可预测.虽然如此,通过使用异步设备IO我们仍然能够创造出更高效的程序. 同步IO时,发出IO请求 ...
- Smobiler与Windows的异步回调差别
Smobiler与Windows的异步回调差别--基于.NET的APP开发和Windows开发差别 基于.NET的APP开发和Windows开发,异步回调差别 Windows app开发 异步回调 S ...
随机推荐
- 大数据篇:Hive
大数据篇:Hive hive.apache.org Hive是什么? Hive是Facebook开源的用于解决海量结构化日志的数据统计,是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射 ...
- 系统警告,Bronya请求支援(两遍最短路)
系统警告,Bronya请求支援 Description 休伯利安号的一行人来到了由逆熵镇守的前文明遗迹[海渊城],他们准备用巨大的传送装置[海渊之眼]进入量子之海,寻找丢失的渴望宝石.然而在行动前夜爱 ...
- Pytest系列(7) - skip、skipif跳过用例
如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 pytest.mark.sk ...
- Appium自动化(1) - 环境准备详细教程
Appium需要用到的工具 链接:https://pan.baidu.com/s/1od9x-1l0ALGRT5T6QFDHWg 提取码:bnhq 安装Appium Pyhton client包 1. ...
- Appium自动化(2) - appium环境安装常见问题的解决方案
如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 问题1:adb检测不到设备 解决 ...
- C++ delete报错解析
C++ delete报错 今天写了如下代码 #include <iostream> #include <algorithm> using namespace std; int ...
- .Net微服务实践(四)[网关]:Ocelot限流熔断、缓存以及负载均衡
目录 限流 熔断 缓存 Header转化 HTTP方法转换 负载均衡 注入/重写中间件 后台管理 最后 在上篇.Net微服务实践(三)[网关]:Ocelot配置路由和请求聚合中我们介绍了Ocelot的 ...
- Spring (六):整合Mybatis
本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...
- python3(二十) module
# 在Python中,一个.py文件就称之为一个模块(Module) # 1.最大的好处是大大提高了代码的可维护性. # 2.可以被其他地方引用 # 3.python内置的模块和来自第三方的模块 # ...
- 解决idea导入maven项目缺少jar包的问题
之前一直用的elipse,现在用idea不熟悉,这里记录一下.这里以idea2017为例. 导入elipse的maven项目,提示缺少jar包,肯定是idea没有给你导包. 第一步,首先确认自己的id ...