Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用ReadFileScatter_C++_Winapi_Asynchronous_Readfile - Fatal编程技术网

C++ 如何使用ReadFileScatter

C++ 如何使用ReadFileScatter,c++,winapi,asynchronous,readfile,C++,Winapi,Asynchronous,Readfile,我一直在尝试在我的代码中使用今天(这听起来正是我所需要的),到目前为止没有很多运气。用谷歌搜索互联网上的错误并没有给我太多的洞察力 文件规定: 数组必须包含足够的元素来存储nNumberOfBytesToRead字节的数据,加上一个元素用于终止NULL。例如,如果要读取40 KB的数据,且页面大小为4 KB,则该数组必须有11个元素,其中10个元素表示数据,1个元素表示NULL 每个缓冲区的大小必须至少等于系统内存页的大小,并且必须在系统内存页大小边界上对齐。系统将一个系统内存页的数据读入每个缓

我一直在尝试在我的代码中使用今天(这听起来正是我所需要的),到目前为止没有很多运气。用谷歌搜索互联网上的错误并没有给我太多的洞察力

文件规定:

数组必须包含足够的元素来存储nNumberOfBytesToRead字节的数据,加上一个元素用于终止NULL。例如,如果要读取40 KB的数据,且页面大小为4 KB,则该数组必须有11个元素,其中10个元素表示数据,1个元素表示NULL

每个缓冲区的大小必须至少等于系统内存页的大小,并且必须在系统内存页大小边界上对齐。系统将一个系统内存页的数据读入每个缓冲区

该函数按顺序将数据存储在缓冲区中。例如,它将数据存储到第一个缓冲区中,然后再存储到第二个缓冲区中,依此类推,直到每个缓冲区都被填满并存储所有数据,或者不再有缓冲区

到目前为止,我一直在尝试这样做。我使用
VirtualAlloc
(确保页面边界约束)分配了一组字节,在列表中添加了一个终止符NULL,确保磁盘上的数据位于系统边界上(隐式地是磁盘扇区大小边界),并发出调用

无需进一步说明,以下是C++中的最低测试用例:

// Setup: c:\tmp\test.dat is a file with at least 12K of stuff. 
// I attempt to read page 2/3, e.g. offset [4096-4096+8192>

// TEST:
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
auto pageSize = systemInfo.dwPageSize;
std::cout << "Page size: "<< pageSize << std::endl;

// Allocate 2 pages that are aligned with one in the middle:
auto buffer = reinterpret_cast<char*>(VirtualAlloc(NULL, pageSize * 3, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));

// Create read buffer:
std::vector<FILE_SEGMENT_ELEMENT> elements;
{
    FILE_SEGMENT_ELEMENT element1;
    element1.Buffer = buffer;
    elements.push_back(element1);
}
{
    FILE_SEGMENT_ELEMENT element2;
    element2.Buffer = buffer + pageSize * 2;
    elements.push_back(element2);
}
{
    FILE_SEGMENT_ELEMENT terminator;
    terminator.Buffer = NULL;
    elements.push_back(terminator);
}

// [..] Physical sector size is normally checked as well. In my case it's 512 bytes, 
// so I guess that's irrelevant here.
//
// Open file:
auto fileHandle = CreateFile(
    "c:\\tmp\\test.dat", 
    GENERIC_READ | GENERIC_WRITE, 
    FILE_SHARE_READ, 
    NULL, 
    OPEN_ALWAYS, 
    FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, 
    NULL);

auto err = GetLastError();
if (err != ERROR_ALREADY_EXISTS && err != ERROR_SUCCESS)
{
    throw std::exception(); // FIXME.
}

OVERLAPPED overlapped;
memset(&overlapped, 0, sizeof(OVERLAPPED));

LARGE_INTEGER tmp;
tmp.QuadPart = 4096; // Read from disk page 1

overlapped.Offset = tmp.LowPart;
overlapped.OffsetHigh = tmp.HighPart;
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

auto succes = ReadFileScatter(fileHandle, elements.data(), pageSize * 2, NULL, &overlapped);
err = GetLastError();

if (!succes && err != ERROR_IO_PENDING && err != ERROR_SUCCESS)
{
    throw std::exception(); // The call always ends up here with error 87: Invalid parameter
}

WaitForSingleObject(overlapped.hEvent, INFINITE);

std::cout << "Call succeeded!" << std::endl;

// FIXME: Proper exception handling.

// Clean up:
VirtualFree(buffer, pageSize * 3, MEM_DECOMMIT | MEM_RELEASE);
CloseHandle(overlapped.hEvent);
CloseHandle(fileHandle);
//安装程序:c:\tmp\test.dat是一个至少包含12K内容的文件。
//我试图阅读第2/3页,例如偏移量[4096-4096+8192>
//测试:
系统信息系统信息;
GetSystemInfo(&systemInfo);
自动页面大小=systemInfo.dwPageSize;

std::如果你在问题文本中明确解释错误模式,会有帮助吗?你是对的,我应该(并将做出更改)。在代码中它说:
调用总是以错误87结束:无效参数
。文件句柄必须使用通用读取权限创建,并且文件标志重叠和文件标志无缓冲标志。-在代码中
文件标志重叠
在哪里?@RbMm Pfff…我不敢相信我已经盯了一整天。该死的…谢谢,这实际上就是解决方案!为什么不简单地
FILE\u SEGMENT\u ELEMENT元素[3];
ReadFileScatter(fileHandle,RTL\u NUMBER\u OF(elements)
?这里的std::vector是什么?它们是
元素。data()==element1