如何在cpprestsdk中提取写入Concurrency::streams::fstream的字节?

How to extract bytes written to Concurrency::streams::fstream in cpprestsdk?

我使用 CPPRESTSDK 创建了一个简单的客户端和服务器。客户端发送图像,在服务器上,我保存传入的文件,然后开始进行处理阶段。

现在我想检查发送的文件是否真的是一个图像文件,而不是其他随机文件。为此,我检查了文件的前几个字节,这让我知道我在处理什么。
这是负责保存文件的片段:

//...
auto fileStream = std::make_shared<Concurrency::streams::ostream >();
Concurrency::streams::ostream outFile = Concurrency::streams::fstream::open_ostream(tmpFileName).get();
*fileStream = outFile;
uintmax_t bytesRead = 0;
int ret = 1;
bool isChecked = false;
while (ret > 0)
{
    ret = request.body().read(fileStream->streambuf(), this->READ_CHUNK).get();
    bytesRead += ret;
    
    if (!isChecked)
    {
        isChecked = true;
        auto streamBuffer = fileStream->streambuf();
        unsigned char byteBuffer[4];
        
        for (int i = 0; i < 4; i++)
        {
            byteBuffer[i] = (unsigned int)streamBuffer.bumpc().get();
            std::cout << byteBuffer[i] << ", ";
        }
        // reset the read pointer
        //streamBuffer.seekpos(std::streampos(), std::ios::in);
        // check and see if this is indeed an image file
        std::string imgFormat = Utils::Misc::GetImageType(byteBuffer);
        if (imgFormat == "")
        {
            fileStream->close().get();
            auto msg = U("Unsupported file has been sent! Expected an image file such as a JPEG, PNG, OR BMP");
            this->ReplyMessage(request, status_codes::BadRequest, json::value::string(msg));
            return;
        }
    }    
    ucout << "--" << bytesRead << U(" bytes read so far[")
          << Utils::Misc::GetFileSize(bytesRead , Utils::Misc::FileSizeTypes::KByte)
          << U(" KB]") << std::endl;
    if (bytesRead > MAX_FILE_SIZE)
        break;
}
// Close the file.
fileStream->close().get();
// ...

这显然失败了,因为 fileStream 是一个 ostream 并且它的 can_read returns false 因此 bumpc() 不起作用。那我该怎么办呢?如何访问底层字节缓冲区并查看到目前为止收到的内容?

更新

使用 requeststreambuf() 也不会产生任何成功,因为文件指针似乎不可移动,因此执行 seekpos(std::streampos(0), std::ios::in) 之类的操作不会将其重置为缓冲区的开头。我在这里错过了什么?

您需要通过显式将 mode 参数传递给 open_ostream function 来打开文件流以供读取和写入。如果不指定此参数,则默认为 std::ios_base::out.

Concurrency::streams::fstream::open_ostream(tmpFileName, std::ios_base::in | std::ios_base::out).get();

然后文件流应该被创建为可读的,你应该能够写入第一个块,向后查找文件的开头,读取四个字节,然后向前查找到第一个块的末尾。

另一种可能更简洁的方法是将第一个块读取到 stringstream,从其中的前四个字节解析图像格式,然后(如果图像格式有效并且文件将被保存)创建文件流,将字符串流的内容写入文件流,然后继续将剩余的文件块直接写入文件流。