具有IO完成端口问题的WriteFile

时间:2012-02-26 08:14:28

标签: c windows winapi io io-completion-ports

我有这个代码,基本上使用IO完成端口写入文件5次。正如你猜测的那样,它不能很好地工作。问题是我希望将“hello”写入文件5次,但它总是只写一个“你好”。我很困惑,因为程序打印“写入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");
}

1 个答案:

答案 0 :(得分:4)

你写了5次文件,但总是写0位 - 你需要将偏移设置为lpOVERLAPPED parameter的一部分。