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 ...
随机推荐
- CentOS下的Docker离线安装
Linux下离线安装Docker 一.基础环境 1.操作系统:CentOS 7.3 2.Docker版本:18.06.1 官方下载地址(打不开可能很慢) 3.百度云Docker 18.06.1地址:h ...
- int不可为null引发的 MyBatis做持久层框架,返回值类型要为Integer问题
MyBatis做持久层框架,返回值类型要为Integer MyBatis 做持久层时,之前没注意,有时候为了偷懒使用了int类型做为返回的类型,这样是不可取的,MyBatis做持久层框架,返回值类型要 ...
- jq ajax请求跨域问题
前端遇到跨域一般和后端协调让后端:
- 计算机网络学习笔记NO.2 物理层
2.1 基本概念 2.1.1 物理层概念 物理层解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体. 物理层主要任务:确定与传输媒体接口有关的一些特性(定义标准) 机械特性:定 ...
- 微信小程序wx:for隐藏遍历的最后一个元素
微信小程序开发时有时会需要从wx:for遍历的元素中选取最后一个来进行相关操作,以下方法以隐藏最后一个元素为例 index==list.length-1 通过获取列表的总长度减一来得到最后一个元素是最 ...
- 如何在VMwareWorkstation中安装Ubuntu系统
文章更新于:2020-03-17 注:如果安装之后重启停留在Write through,则关闭客户机,将 ISO 镜像换为物理光驱,或取消勾选开机连接.再次开机即可正常进入系统. 文章目录 一.安装环 ...
- python学习 0 python简介
一.Python简介 python是一门简单易学又功能强大的编程语言.它具有高效的高级数据结构和简单而有效的面向对象编程的特性.python优雅的语法和动态类型.以及其解释性的性质,使它在许多领域和大 ...
- spring boot 学习(一)——在idea建立第一个spring boot项目
1.打开idea->点击file->点击new->点击project->点击Spring Initializr->点击default 2.这是springboot的启动类 ...
- JAVA中使用Date和SimpleDateFromat类表示时间
转自:https://www.imooc.com/code/2335 仅做个人学习保存之用,侵删! 在程序开发中,经常需要处理日期和时间的相关数据,此时我们可以使用 java.util 包中的 Dat ...
- 29.2 Iterator 迭代器
/* * 集合的遍历方式: * 1.toArray(),可以把集合转换成数组,然后遍历数组即可 * 2.iterator(),可以返回一个迭代器对象,我们可以通过迭代器对象来迭代集合 * * Iter ...