如何在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()
不起作用。那我该怎么办呢?如何访问底层字节缓冲区并查看到目前为止收到的内容?
更新
使用 request
的 streambuf()
也不会产生任何成功,因为文件指针似乎不可移动,因此执行 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
,从其中的前四个字节解析图像格式,然后(如果图像格式有效并且文件将被保存)创建文件流,将字符串流的内容写入文件流,然后继续将剩余的文件块直接写入文件流。
我使用 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()
不起作用。那我该怎么办呢?如何访问底层字节缓冲区并查看到目前为止收到的内容?
更新
使用 request
的 streambuf()
也不会产生任何成功,因为文件指针似乎不可移动,因此执行 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
,从其中的前四个字节解析图像格式,然后(如果图像格式有效并且文件将被保存)创建文件流,将字符串流的内容写入文件流,然后继续将剩余的文件块直接写入文件流。