为什么在C++中可以用char数组上传图片,而不能用equal std::istringstream上传图片?
Why images can be uploaded with char array but not with equal std::istringstream in C++?
考虑一下下面的代码:
char buffer[4000];
size_t bytes = recv(fd, buffer, 4000, 0);
write(pipefd[1], buffer, bytes);
close(pipefd[1]);
wait(NULL);
这里是读取fd,向管道写入数据,关闭管道。这允许最终上传可以渲染的小图像。但是,如果我做同样的事情,只用 std::istringstream 替换 char 数组,如下例所示:
char buffer[4000];
size_t bytes = recv(fd, buffer, 4000, 0);
std::istringstream data(buffer);
write(pipefd[1], data.str().c_str(), bytes);
close(pipefd[1]);
wait(NULL);
然后图像上传但无法渲染。 (通过管道这个 C++ 程序与 php-cgi 脚本通信)。
另外:
if (strcmp(data.str().c_str(), buffer) == 0)
// returns true
我很好奇为什么会这样。
如果你在 Windows 上 运行,那么 C++ 流在读取和写入时会自动在单个 \n
之前添加回车符 return \r
。修复很简单
std::istringstream data(buffer, std::ios::binary);
MacOS 可配置为使用 \r
、\n
、\r\n
中的任何一个。你永远不应该期望使用什么,并始终对二进制数据应用流模式 std::ios::binary
。
然而,这两个代码片段都无效,std::istringstream data(buffer)
和 std::string data(buffer)
使用 data
中的字节,直到遇到第一个零字节。
std::istringstream data(buffer);
这假设 buffer
是一个 null-terminated 字符串。二进制数据通常包含 0x00
字节,因此您最终会截断 buffer
内容。
改用这个:
std::istringstream data(std::string(buffer, bytes), std::ios::binary);
考虑一下下面的代码:
char buffer[4000];
size_t bytes = recv(fd, buffer, 4000, 0);
write(pipefd[1], buffer, bytes);
close(pipefd[1]);
wait(NULL);
这里是读取fd,向管道写入数据,关闭管道。这允许最终上传可以渲染的小图像。但是,如果我做同样的事情,只用 std::istringstream 替换 char 数组,如下例所示:
char buffer[4000];
size_t bytes = recv(fd, buffer, 4000, 0);
std::istringstream data(buffer);
write(pipefd[1], data.str().c_str(), bytes);
close(pipefd[1]);
wait(NULL);
然后图像上传但无法渲染。 (通过管道这个 C++ 程序与 php-cgi 脚本通信)。
另外:
if (strcmp(data.str().c_str(), buffer) == 0)
// returns true
我很好奇为什么会这样。
如果你在 Windows 上 运行,那么 C++ 流在读取和写入时会自动在单个 \n
之前添加回车符 return \r
。修复很简单
std::istringstream data(buffer, std::ios::binary);
MacOS 可配置为使用 \r
、\n
、\r\n
中的任何一个。你永远不应该期望使用什么,并始终对二进制数据应用流模式 std::ios::binary
。
然而,这两个代码片段都无效,std::istringstream data(buffer)
和 std::string data(buffer)
使用 data
中的字节,直到遇到第一个零字节。
std::istringstream data(buffer);
这假设 buffer
是一个 null-terminated 字符串。二进制数据通常包含 0x00
字节,因此您最终会截断 buffer
内容。
改用这个:
std::istringstream data(std::string(buffer, bytes), std::ios::binary);