Overlapped I/O是Win32的一项技术,你可以要求操作系统给你传送数据,并且在传送完毕时通知你,这项技术使你的程序在I/O进行过程中仍然能够继续处理事务。
其中I/Ocompletion ports特别显得重要,因为他们是唯一适用于高负载服务器(必须同时维护许多连接线路)的一个技术。
Win32中有三个基本的函数用来执行I/O,他们是CreateFile(),ReadFile(),WriteFile(),CreateFile()可以用来打开各式各样的资源,包括:文件(硬盘、软盘、光盘或其它)、串行口和并行口,Named pipes、Console。
CreateFile(
LPCTSTR lpFileName,//指向文件名称
DWORDdwDesiredAccess,//存取模式
DWORD dwShareMode,//共享模式
LPSECURITY_ATTRIBUTESlpSecurityAttributes,//指向安全属性结构
DWORDdwCreationDisposition,//如何产生
DWORDdwFlagAndAttributes,//文件属性
HANDLE hTemplateFile//一个临时文件,将拥有全部的属性拷贝
)
第六个参数设为FILE_FLAG_OVERLAPPED,可以使用overlapped(异步)调用。
BOOLReadFile(
HANDLEhFile, //文件的句柄
LPVOIDlpBuffer, //用于保存读入数据的一个缓冲区
DWORDnNumberOfBytesToRead, //要读入的字节数
LPDWORD lpNumberOfBytesRead,//指向实际读取字节数的指针
LPOVERLAPPEDlpOverlapped //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
);
BOOLReadFile(
HANDLEhFile, //文件的句柄
LPVOIDlpBuffer, //用于保存写入数据的一个缓冲区
DWORDnNumberOfBytesToWrite, //要写入的字节数
LPDWORDlpNumberOfBytesWritten, //指向实际读取字节数的指针
LPOVERLAPPEDlpOverlapped //如文件打开时指定了FILE_FLAG_OVERLAPPED
);
Overlapped结构如下:
typedef struct _OVERLAPPED
{
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
}OVERLAPPED,*LPOVERLAPPED
调用GetOverlappedResult()可查看文件操作是否成功,函数原型如下:
BOOL GetOverlappedResult(HANDLE hFile,LPOVERLAPPEDlpOverlapped,LPDWORD lpNumberOfBytesTransferd,BOOL bWait);
对文件进行OVERLAPPEDI/O的缺点:由于操作系统在面对快速数据传输时,选择将你的进程先停下来,所以你的进程遗失至少(平均)12ms的时间。但如果你企图搬移的是1MB的数据,I/O操作会被先记录下来,你的线程可以继续进行。对于一系列少于32kb的数据传输请求,overlapped I/O所花的时间比单纯调用ReadFile所花时间要多15%。一种合理的变化是,以少量的线程负责所有的硬盘I/O,然后把对这些线程的I/O请求,保持一个队列之中。
有两种情况,overlappedI/O总是同步执行,甚至即使FILE_FLAG_NO_BUFFERING已经制定。第一种情况是你进行一个写入操作而造成文件的扩展,第二种情况是你读写一个压缩文件。