您的位置:首页 > 移动开发

Code - Windows Overlapped

2020-03-05 09:11 507 查看
[code]#include <Windows.h>
#include <stdio.h>

#define KB(_byte)   (_byte*1024)
#define MB(_byte)   (KB(_byte)*1024)
#define GB(_byte)   (MB(_byte)*1024)

int file_Overlapped()
{
    HANDLE hFile;
    OVERLAPPED overlap;
    BOOL ret;
    DWORD readByte = 0;//实际读到的值
    BYTE *buf =  malloc( sizeof(BYTE) * GB(1) );
    DWORD error_code;

    hFile = CreateFile("./TEST_FILE_W", //文件名
        GENERIC_WRITE,  //访问方式
        0,              //共享模式
        NULL,           //安全属性
        OPEN_EXISTING,  //创建描述
        FILE_FLAG_OVERLAPPED,
        NULL
        );

    if(INVALID_HANDLE_VALUE == hFile)
    {
        return -1;
    }

    memset(&overlap,0,sizeof(OVERLAPPED) );

    ret = WriteFile(hFile,buf,GB(1),&readByte,&overlap);
    if(ret)
    {
        printf("无需使用重叠I/O方式,写入完成\n\
               实际写入%d字节\n",readByte);
    }
    else
    {
        error_code = GetLastError();
        if(error_code == ERROR_IO_PENDING)
        {

            printf("overlapped操作被放到队列中等待执行\n");
        }
        else
        {
            printf("错误:%d\n",error_code);
        }
    }

    while(1)
    {
        //WaitForSingleObject(hFile,INFINITE);//读取完成 事件有信号

        printf("wait ok\n");
        //TRUE:等到异步操作结束才返回,FALSE:立即返回
        ret = GetOverlappedResult(  hFile,
                                    &overlap,
                                    &readByte,
                                    FALSE
                                    );
        if(ret)
        {
            printf("写入完成\n");
            break;
        }
        else
        {
            error_code = GetLastError();
            if(error_code == ERROR_IO_INCOMPLETE)
            {
                printf("尚未写入完成\n");
            }
            else
            {
                printf("发生错误\n");
            }
        }
    }
    CloseHandle(hFile);
    free(buf);

    return EXIT_SUCCESS;
}

int event_Overlapped()
{
    HANDLE hFile;
    HANDLE hEvent;
    OVERLAPPED overlap;
    BOOL ret;
    DWORD readByte = 0;//实际读到的值
    BYTE buf[1024] = {0};
    DWORD error_code;

    hFile = CreateFile("./TEST_FILE",   //文件名
                        GENERIC_READ,   //访问方式
                        0,              //共享模式
                        NULL,           //安全属性
                        OPEN_EXISTING,  //创建描述
                        FILE_FLAG_OVERLAPPED,
                        NULL
                        );

    if(INVALID_HANDLE_VALUE == hFile)
    {
        return -1;
    }

    memset(&overlap,0,sizeof(OVERLAPPED) );
    overlap.Offset = 0;//文件偏移
    hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//手动 初始无信号
    overlap.hEvent = hEvent;//针对每个操作使用不同的结构和事件

    ret = ReadFile(hFile,buf,1024,&readByte,&overlap);
    if(ret)
    {
        printf("无需使用重叠I/O方式,读取完成\n\
               实际读到%d字节\n",readByte);
    }
    else
    {
        error_code = GetLastError();
        if(error_code == ERROR_IO_PENDING)
        {

            printf("overlapped操作被放到队列中等待执行\n");
        }
        else
        {
            printf("错误:%d\n",error_code);
        }
    }

    while(1)
    {
        //WaitForSingleObject(overlap.hEvent,INFINITE);读取完成 事件有信号

        //TRUE:等到异步操作结束才返回,FALSE:立即返回
        ret = GetOverlappedResult(hFile,&overlap,&readByte,FALSE);
        if(ret)
        {
            printf("读取完成\n");
            break;
        }
        else
        {
            printf("尚未读取完成\n");
        }
    }
    CloseHandle(hFile);

    return EXIT_SUCCESS;
}

VOID CALLBACK FileIOCompletionRoutine(
    /*
    *The I/O completion status. This parameter can be one of the system error codes.
    **/
    _In_     DWORD dwErrorCode,
    /*
    *The number of bytes transferred. If an error occurs, this parameter is zero.
    **/
    _In_     DWORD dwNumberOfBytesTransfered,
    /*
    *A pointer to the OVERLAPPED structure specified by the asynchronous I/O function.
    *The system does not use the OVERLAPPED structure after the completion routine is called,
    *so the completion routine can deallocate the memory used by the overlapped structure.
    **/
    _Inout_  LPOVERLAPPED lpOverlapped
)
{
    if(dwErrorCode == NO_ERROR)
    {
        printf("dwErrorCode:%lu \ndwNumberOfBytesTransfered:0x%X \nlpOverlapped:%p \n",dwErrorCode,dwNumberOfBytesTransfered,lpOverlapped);
    }
    lpOverlapped->hEvent = (HANDLE)1;
}

int callback_Overlapped()
{
    HANDLE      hFile;
    OVERLAPPED  st_overlap;
    BOOL        ret;
    char*       write_buf;
    DWORD       error_code;
    DWORD       apc_ret;

    hFile = CreateFile("COM3",                                      //文件名
                        GENERIC_READ | GENERIC_WRITE,               //访问方式
                        0,                                          //共享模式
                        NULL,                                       //安全属性
                        OPEN_EXISTING,                              //创建描述
                        FILE_FLAG_OVERLAPPED,                       //重叠选项
                        NULL                            
                        );

    if(INVALID_HANDLE_VALUE == hFile)
    {
        fprintf(stderr,"The file open fail\n");
        return -1;
    }

    write_buf =  malloc( sizeof(BYTE) * GB(1) );
    if(!write_buf)
    {
        CloseHandle(hFile);
        fprintf(stderr,"Write buffer alloc fail\n");
        return -1;
    }

    memset(&st_overlap,0,sizeof(OVERLAPPED) );
    st_overlap.Offset = 0;//文件偏移
    st_overlap.hEvent = 0;//异步过程调用模式此参数可自定义(HANDLE就是void*)

    //ret = WriteFileEx(    hFile,                      //文件句柄
    //                      write_buf,                  //写入缓存
    //                      MB(1000),                   //缓存大小
    //                      &st_overlap,                //重叠结构指针
    //                      FileIOCompletionRoutine     //完成回调函数
    //                      );

    ret = ReadFileEx(   hFile,                      //文件句柄
                        write_buf,                  //写入缓存
                        MB(1000),                   //缓存大小
                        &st_overlap,                //重叠结构指针
                        FileIOCompletionRoutine     //完成回调函数
                        );
    if(ret)
    {
        printf("overlapped操作被放到队列中等待执行\n");
    }
    else
    {
        error_code = GetLastError();
        printf("error code:%d\n",error_code);
    }

WAIT_APC:
    apc_ret = WaitForSingleObjectEx(hFile,1,TRUE);
    
    switch (apc_ret)
    {
    case WAIT_ABANDONED:
        printf("拥有mutex的线程在结束时没有释放核心对象\n");
        break;
    case WAIT_IO_COMPLETION:
        printf("等待用户模式APC队列结束\n");
        break;
    case WAIT_OBJECT_0:
        printf("核心对象已被激活\n");
        break;
    case WAIT_TIMEOUT:
        printf("超时时间到\n");
        break;
    case WAIT_FAILED:
        printf("出现错误\n");
    }

    if(apc_ret != WAIT_IO_COMPLETION)
    {
        goto WAIT_APC;  
    }

    printf("WAIT_IO_COMPLETION");
    CloseHandle(hFile);
    free(write_buf);

    return EXIT_SUCCESS;
}

int main()
{
    event_Overlapped();
    return 0;
}

 

转载于:https://my.oschina.net/mlgb/blog/361737

  • 点赞
  • 收藏
  • 分享
  • 文章举报
chijiaozhao5384 发布了0 篇原创文章 · 获赞 0 · 访问量 164 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: