将 lStream 复制到字节数组

Copy lStream to byte array

HRESULT hr = URLOpenBlockingStreamW(nullptr, cstring, &pStream, 0, nullptr);
if (FAILED(hr))
{
    return 1;
}

char buffer[4096];
do
{
    DWORD bytesRead = 0;
    hr = pStream->Read(buffer, sizeof(buffer), &bytesRead);
        
    if (bytesRead > 0)
    {
        std::cout.write(buffer, bytesRead);
    }
        
} while (SUCCEEDED(hr) && hr != S_FALSE);

//memcpy(&bytesRead, arr, sizeof(buffer));
if (FAILED(hr))
{
    return 2;
}

return 0;

我以前做的是下载文件并从那里读取,但现在我试图直接将文件下载到内存中。我不需要被喂食。我对此很陌生,想要一个解释,如果有的话,这样我就可以真正地学习它。我发现的唯一示例是上面的代码。我不明白如何将字节直接从流复制到字节数组。 (或如何从网站上的文件中获取准确的文件大小)。

在 C# 中,只需将文件下载到一个路径并使用就容易多了 File.ReadAllBytes(path);

编辑:这是在 C++ 中,而不是像旧版本那样的 C#(如果您无法从代码片段中分辨出来)。

IStream 有一个 Stat() 方法来查询流的大小(除其他外)。查询大小,然后分配一个那个大小的字节数组,然后Read()到数组中。

如果 Stat() 无法确定大小(因为下载是流式的并且预先不知道完整大小),那么只需使用 std::vector 作为字节数组,这样它将随着您向其写入更多字节而增长。

HRESULT hr = URLOpenBlockingStreamW(nullptr, cstring, &pStream, 0, nullptr);
if (FAILED(hr))
    return 1;

std::vector<char> bytes;

STATSTG stat = {};
hr = pStream->Stat(&stat, STATFLAG_NONAME | STATFLAG_NOOPEN);
if (SUCCEEDED(hr))
{
    size_t size = stat.cbSize.QuadPart;
    if (size > 0)
    {
        bytes.resize(size);
        char *buffer = bytes.data();
        DWORD bytesRead;

        do
        {
            hr = pStream->Read(buffer, size, &bytesRead);
            if (FAILED(hr))
                return 2;

            if (bytesRead == 0)
                break;

            buffer += bytesRead;
            size -= bytesRead;
        }
    }
}
else
{
    char buffer[1024];
    DWORD bytesRead;

    do
    {
        hr = pStream->Read(buffer, sizeof(buffer), &bytesRead);
        if (FAILED(hr)
            return 3;

        if (bytesRead == 0)
            break;

        bytes.insert(bytes.end(), buffer, buffer + bytesRead);
    }
    while (true);
}

// use bytes as needed...

return 0;