overlapped编程

复制代码
int main(void)
{
    BOOL fOk = FALSE;

    HANDLE hFileSrc = CreateFile(_T("test.txt"),GENERIC_READ,FILE_SHARE_READ,NULL,
        OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

    HANDLE hFileDest = CreateFile(_T("cpy_test.txt"),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
         FILE_FLAG_OVERLAPPED,NULL);
    if (hFileSrc == INVALID_HANDLE_VALUE ||
        hFileDest == INVALID_HANDLE_VALUE) 
    {
        cout<<GetLastError()<<endl;
        system("pause");
        return 1;
    }

    BOOL ret = FALSE;
    char str[1024] = {0};
    DWORD dwNumberRead = 0;
    OVERLAPPED ov = {0};
    ov.hEvent = NULL;
    ov.Offset = 0;
    ov.OffsetHigh = 0;
    while (true)
    {
        ret = ReadFile(hFileSrc,str,1023,&dwNumberRead,&ov);
        if (ret == FALSE)
        {
            if (GetLastError() == ERROR_IO_PENDING)
            {
                GetOverlappedResult(hFileSrc,&ov,&dwNumberRead,true);
            }
            else
            {
                cout<<GetLastError()<<endl;
                break;
            }
        }
        if (ov.InternalHigh == 0)
        {
            break;
        }
        str[ov.InternalHigh] = 0;
        cout<<str<<endl;
        ov.Offset += ov.InternalHigh;
        memset(str,0,sizeof(str));
    }
}
复制代码

代码基本都是在读取的时候立即返回,而不是类似阻塞IO那样,一直到读完才返回,基本原理也就是把这个把IO放进队列里面,如果请求只是放进队列里面而没有处理,getlasterror返回的是ERROR_IP_PENDING,这个时候GetOverlappedResult是等待读完再继续,也可以WaitSingleObejct要读取的文件或者overlapped里面的hevent来等待读完..

 

刚写完这段代码就有点奇怪,既然要等待他读完才能继续执行,为什么还要用异步,用同步不也可以??后来想了下,这样做的好处就是可以让原本等待在IO操作完成的时间中做其他事情,然后到一定的地方在等待完成,如果使用非阻塞IO,在IO操作完成操作后需要调用一段函数,而这段函数又与IO操作无关,这样无缘无故浪费了中间一段时间,还不如在IO操作前做些其他的事情....最近工作用到的读串口也是这样,虽然也是在调用ReadFile后立即等待操作完成,但是如果哪天需要在中间加入 一些操作,那修改起来就很麻烦...

 

还有一个比较2B的时候,我在调用CreateFile的时候使用了FILE_FLAG_NO_BUFFERING这个标志,结果读的时候总是错误,说是无效参数,后来发现是在CreateFile的时候指定了FILE_FLAG_NO_BUFFERING

 

MSDN是这样说的:

The file or device is being opened with no system caching for data reads and writes. This flag does not affect hard disk caching or memory mapped files.

There are strict requirements for successfully working with files opened with CreateFile using the FILE_FLAG_NO_BUFFERING flag, for details see File Buffering.

 

windows核心编程里面则说指定了这个标志后读写必须使用64的倍数....

 

需要注意的是,传入的是overlapped的地址,所以在overpaeed作用域过后,如果IO操作还没完成,则会发生未知错误

如下代码

void ReadData(HANDLE hFile)
{
    OVERLAPPED ov = {0};
    ov.hEvent = NULL;
    BYTE b[100];
    ReadFile(hFile,b,100,&ov);
}
posted @   linyilong  阅读(2332)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示