2015-11-03 162 views
0

我試圖在Windows下實現快速IO,並以重疊IO的方式工作。在我的研究中,Unbuffered IO需要頁面對齊的緩衝區。我試圖在下面的代碼中實現它。但是,我偶爾會在完成讀取之前以及讀取頁面對齊的緩衝區之後偶爾使Readfiles上次錯誤報告無法訪問(錯誤998,ERROR_NOACCESS)。有時候16.有時4等Readfile()偶爾會返回998/ERROR_NOACCESS

我不能爲我的生活弄清楚爲什麼我偶爾會拋出一個錯誤。任何見解都會有所幫助。

ci::BufferRef CinderSequenceRendererApp::CreateFileLoadWinNoBufferSequential(fs::path path) { 
HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_SEQUENTIAL_SCAN, 0); 

if (file == INVALID_HANDLE_VALUE) 
{ 
    console() << "Could not open file for reading" << std::endl; 
} 

ci::BufferRef latestAvailableBufferRef = nullptr; 

LARGE_INTEGER nLargeInteger = { 0 }; 

GetFileSizeEx(file, &nLargeInteger); 

// how many reads do we need to fill our buffer with a buffer size of x and a read size of y 
// Our buffer needs to hold 'n' sector sizes that wil fit the size of the file 

SYSTEM_INFO si; 
GetSystemInfo(&si); 
long readAmount = si.dwPageSize; 

int numReads = 0; 
ULONG bufferSize = 0; 

// calculate sector aligned buffer size that holds our file size 
while (bufferSize < nLargeInteger.QuadPart) 
{ 
    numReads++; 
    bufferSize = (numReads) * readAmount; 
} 

// need one page extra for null if we need it 
latestAvailableBufferRef = ci::Buffer::create(bufferSize + readAmount); 

if (latestAvailableBufferRef != nullptr) 
{ 
    DWORD outputBytes = 1; 

    // output bytes = 0 when OEF 
    void* address = latestAvailableBufferRef->getData(); 
    DWORD bytesRead = 0; 
    while (outputBytes != 0) 
    { 
     bool result = ReadFile(file, address, readAmount, &outputBytes, 0); 
     if (!result)//&& (outputBytes == 0)) 
     { 
      getLastReadError(); 
     } 

     address = (void*)((long)address + readAmount); 
     bytesRead += outputBytes; 

    } 
} 

CloseHandle(file); 

// resize our buffer to expected file size? 
latestAvailableBufferRef->resize(nLargeInteger.QuadPart); 

return latestAvailableBufferRef; 
} 
+1

將地址轉換爲'long'通常會破壞64位版本。 –

+0

這完全是它。我發佈後立刻就發現了它。 DERP。謝謝。 – vade

+0

此外,您的代碼正在檢測API錯誤,但沒有對它們做出反應。如果'CreateFile()'無法打開文件,那麼您仍在繼續處理無效文件句柄。如果'GetFileSizeEx()'失敗,您仍在繼續使用無效的文件大小。如果'ReadFile()'失敗,您仍在繼續處理未讀數據。如果發生錯誤,請停止正在執行的操作,關閉文件並根據需要處理錯誤。 –

回答

0

長久以來 - 我截斷了我的指針地址。咄。感謝@ jonathan-potter