c++ - FILE_FLAG_NO_BUFFERING with overlapped I/O - bytes read zero -
i observe weird behavior while using flag file_flag_no_buffering overlapped i/o. invoke series of readfile() function calls , query statuses later using getoverlappedresult().
the weird behavior speaking of though file handles , readfile() calls returned without bad error(except error_io_pending expected), 'bytes read' value returned getoverlappedresult() call 0 of files, , each time run code - different set of files. if remove file_flag_no_buffering, things start working , no bytes read value zero.
here how have implemented overlapped i/o code file_flag_no_buffering.
long overlappedio(std::vector<std::string> &filepathnamevectorref) { long totalbytesread = 0; dword bytesread = 0; dword bytestoread = 0; std::map<handle, overlapped> handlemap; handle handle = invalid_handle_value; dword accessmode = generic_read; dword sharemode = 0; dword createdisposition = open_existing; dword flags = file_flag_overlapped | file_flag_no_buffering; dword filesize; large_integer li; char * buffer; bool success = false; for(unsigned int i=0; i<filepathnamevectorref.size(); i++) { const char* filepathname = filepathnamevectorref[i].c_str(); handle = createfile(filepathname, accessmode, sharemode, null, createdisposition, flags, null); if(handle == invalid_handle_value){ fprintf(stdout, "\n error occured: %d", getlasterror()); fprintf(stdout," getting handle: %s",filepathname); continue; } getfilesizeex(handle, &li); filesize = (dword)li.quadpart; bytestoread = (filesize/g_bytesperphysicalsector)*g_bytesperphysicalsector; buffer = static_cast<char *>(virtualalloc(0, bytestoread, mem_commit, page_readwrite)); overlapped overlapped; zeromemory(&overlapped, sizeof(overlapped)); overlapped * lpoverlapped = &overlapped; success = readfile(handle, buffer, bytestoread, &bytesread, lpoverlapped); if(!success && getlasterror() != error_io_pending){ fprintf(stdout, "\n error occured: %d", getlasterror()); fprintf(stdout, "\n reading file %s",filepathname); closehandle(handle); continue; } else handlemap[handle] = overlapped; } // status check , bytes read value for(std::map<handle, overlapped>::iterator iter = handlemap.begin(); iter != handlemap.end(); iter++) { handle handle = iter->first; overlapped * overlappedptr = &(iter->second); success = getoverlappedresult(handle, overlappedptr, &bytesread, true); if(success) { /* bytesread value in cases unexpectedly 0 */ /* no file of size 0 or lesser 512 bytes(physical volume sector size) */ totalbytesread += bytesread; closehandle(handle); } } return totalbytesread; }
with file_flag_no_buffering absent, totalbytesread value 57 mb. flag present, totalbytesread value lower 57 mb , keeps changing each time run code ranging 2 mb 15 mb.
your calculation of bytestoread produce 0 result when file size less g_bytesperphysicalsector. small files requesting 0 bytes.
Comments
Post a Comment