无法读取 .jpg 二进制数据,缓冲区只有 4 个字节的数据

康纳

我的问题几乎与这个没有答案的问题完全一样我正在尝试读取 .jpg 的二进制数据,以在使用 C++ 的简单 Web 服务器上作为 HTTP 响应发送。读取数据的代码如下。

FILE *f = fopen(file.c_str(),"rb");
if(f){
    fseek(f,0,SEEK_END);
    int length = ftell(f);
    fseek(f,0,SEEK_SET);
    char* buffer = (char*)malloc(length+1);
    if(buffer){
      int b = fread(buffer,1,length,f);
      std::cout << "bytes read: " << b << std::endl;
    }
    fclose(f);
    buffer[length] = '\0';
    return buffer;
  }
  return NULL;

当发出对图像的请求并运行此代码时,fread() 返回正在读取的 25253 个字节,这似乎是正确的。但是,当我执行 strlen(buffer) 时,我只得到 4。当然,当图像尝试显示时,这会在浏览器上出现错误。我还尝试将 HTTP 内容长度手动设置为 25253,但随后我收到 curl 错误 18,表明传输提前结束(因为仅存在 4 个字节)。

正如他们的问题中提到的另一张海报,图像的第 5 个字节(我假设大多数 .jpg 图像)是 0x00,但我不确定这是否对保存到缓冲区有影响。

我已经验证我加载的.jpg图像在目录中,有效,并且正常打开时可以正常显示。我也尝试了 2 种不同的加载二进制数据的方法,而且都只给出了 4 个字节,所以我真的很茫然。任何帮助深表感谢。

超级诱惑

当发出对图像的请求并运行此代码时,fread() 返回正在读取的 25253 个字节,这似乎是正确的。但是,当我执行 strlen(buffer) 时,我只得到 4 个。

嗯,这是你的问题:你读取的是二进制数据,而不是文本,这意味着像换行符或空字符这样的特殊字符不是表示文本结构的东西,它的简单数字。

strlen是一个函数,可以为您提供除'\0'之外的字符数0然而,在像 jpeg 这样的二进制文件中,通常有十几个零,并且由于二进制标头结构,位置 5 处似乎总是有一个零,因此strlen将在它找到的第一个位置停止并返回 4。

此外,您似乎对尝试将此“文本解释”jpeg 发送到 HTTP 服务器这一事实感到困惑。当然它会抱怨,因为你不能简单地在 HTTP 中将二进制数据作为文本发送,你要么必须对其进行编码,base64 非常流行,要么设置内容长度标头。当然,您还必须通过设置正确的 MIME 标头来告诉 HTTP 客户端/服务器类型。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将二进制数据写入缓冲区

在协议缓冲区消息中存储二进制数据缓冲区

使用 ifstream 从二进制文件一次读取 4 个字节

如何将4个字节的二进制数据解压缩为3个字节和1个字节的值?

从二进制文件解包 4 字节无符号整数给出 struct.error:解包需要 4 字节的缓冲区

NodeJS读取二进制浮点缓冲区

读取二进制数据,seek 无法正常工作

在VB.NET中读取时,从文件中排除二进制数据的前“ x”个字节

二进制文件格式:为什么系统会读取所有4个字节并将其正确显示为25736483

在C ++中管理二进制数据的缓冲区

使用协议缓冲区发送二进制数据的正确方法是什么?

如何读取“字”具有不同字节长度的二进制数据文件?

无法读取Lua 5.1上二进制文件的每个字节

读取二进制文件并遍历每个字节

读取二进制数据问题

读取二进制数据

二进制数据读取

将十六进制字符串转换为二进制数据并放入缓冲区

协议缓冲区-将具有相同.proto文件的二进制数据文件合并到一个文件中

GDB检查数据显示格式,从连续8个字节到4个字节

如何将数据 URI 转换为缓冲区(带二进制的字符串)?

C ++:将读取的二进制文件存储到缓冲区

将int写入二进制缓冲区(Android)并使用C ++读取

C二进制文件读取缓冲区声明位置差异

从Julia的二进制文件中读取4字节字

如何从二进制文件中读取除最后X个字节以外的所有字节?

尝试从二进制文件中提取特定字节的数据时,从 struct.unpack 中获取缓冲区大小错误

读取2字节utf8二进制数据

使用 tobytes() 写入二进制数据无法使用 Windows 上的软件读取