2012-02-26 87 views
1

我有這樣的代碼基本上使用IO完成端口寫入文件5次。正如你猜測的那樣,它不能很好地工作。問題是,我希望將「你好」寫入文件5次,但最終總是隻寫一個「你好」。我很困惑,因爲程序打印「寫了5個字節」5次,所以我認爲寫入完成了。使用IO完成端口寫文件問題

任何人都可以看到這個問題嗎?

#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"); 
} 

回答

4

你寫的5倍到該文件,但始終定位0 - 你需要設置偏移量爲lpOVERLAPPED parameter的一部分。

+4

對於所有五個I/O操作,您還使用了相同的「OVERLAPPED」結構,這意味着所有結果都將相互衝突。每個操作應該使用不同的'OVERLAPPED'結構。 – 2012-02-26 11:32:47