c - WriteFile 与 IO 完成端口问题

标签 c windows winapi io io-completion-ports

我有这段代码,基本上使用 IO 完成端口将文件写入 5 次。如您所料,它的效果不是很好。问题是我希望将“hello”写入文件 5 次,但最终总是只写入一个“hello”。我很困惑,因为该程序打印了 5 次“写入 5 个字节”,所以我认为写入完成正常。

有人能看出这有什么问题吗?

#include <windows.h>
#include <stdio.h>

#define IOCP_NOMORE 3
#define IOCP_WRITE 1

HANDLE hWriteIoCp;

typedef struct _OVERLAPIOINFO {
    OVERLAPPED overlapped;
    HANDLE hFile;
} OVERLAPIOINFO;

HANDLE CreateNewCompletionPort()
{
    return CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
}

BOOL AssociateFileCompletionPort(HANDLE hIoPort, HANDLE hFile, DWORD completionKey)
{
    HANDLE h = CreateIoCompletionPort(hFile, hIoPort, completionKey, 0);
    return h == hIoPort;
}

DWORD WINAPI SaveFileWorkerThread(void *empty)
{
    ULONG_PTR completionKey;
    BOOL completionStatus;
    DWORD bytesTransferred;
    DWORD err;
    OVERLAPPED *overlap;
    OVERLAPIOINFO *info;

    for (;;)
    {
        completionStatus = GetQueuedCompletionStatus(hWriteIoCp, &bytesTransferred, &completionKey, &overlap, INFINITE);
        err = GetLastError();

        if (completionStatus) 
        {
            switch(completionKey)
            {
            case IOCP_WRITE:
                fprintf(stderr, "wrote %d bytes\n", bytesTransferred);
                break;

            case IOCP_NOMORE:
                fprintf(stderr, "done!");
                info = (OVERLAPIOINFO *) overlap;
                CloseHandle(info->hFile);
                free(info);
                break;

            }
        } 
        else 
        {
            if (overlap != NULL) 
                fprintf(stderr, "overlap not null");
            else 
                if (err != WAIT_TIMEOUT)
                    fprintf(stderr, "timeout");
        }
    }

}

int main()
{
    HANDLE hSaveFile;
    OVERLAPIOINFO *saveFileOverlap;
    char buf[] = "hello";

    hWriteIoCp = CreateNewCompletionPort();
    CreateThread(NULL, 0, SaveFileWorkerThread, NULL, 0, NULL);

    if ((hSaveFile = CreateFileA("C:\\received.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, 
        CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE)
        fprintf(stderr, "unable to create file\n");

    saveFileOverlap = (OVERLAPIOINFO *) malloc(sizeof(*saveFileOverlap));
    memset(&(saveFileOverlap->overlapped), 0, sizeof(saveFileOverlap->overlapped));
    saveFileOverlap->hFile = hSaveFile;
    AssociateFileCompletionPort(hWriteIoCp, saveFileOverlap->hFile, IOCP_WRITE);

    for (int i = 0; i < 5; i++)
        if (!WriteFile(saveFileOverlap->hFile, buf, strlen(buf), NULL, &(saveFileOverlap->overlapped)))
            if (GetLastError() != ERROR_IO_PENDING)
                fprintf(stderr, "error writing file\n");

    PostQueuedCompletionStatus(hWriteIoCp, 0, IOCP_NOMORE, &(saveFileOverlap->overlapped));

    system("pause");
}

最佳答案

您向文件写入了 5 次,但始终写入位置 0 - 您需要将偏移量设置为 lpOVERLAPPED parameter 的一部分.

关于c - WriteFile 与 IO 完成端口问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9451557/

相关文章:

c++ - PfCreateInterface 返回错误 120(未实现)

c++ - 如何检索 netstat 命令的结果

c - 拦截winsock recvfrom函数给出无效地址错误

c++ - 检测窗口何时停止移动?

c - IAT Hook Internet Explorer

c - 为私钥分配内存的合理安全、合理便携的方法是什么?

android - LibSNDfile/Obeo 音频录制 Android 未正确写入 header

c - 在 C 中显示#define 值

c - 运行 Tensorflow session 会产生一个空张量

c++ - winapi listview检查项c++