C++ 写入二进制文件字节错乱来源

C++ 写入二进制文件字节错乱来源

问题背景:利用OpenCV对图片进行处理后,为了将图片进行网络传输,需要将图片加载至内存中传输。 imread不能满足此场景,此处使用imencode函数。在将imencode函数返回 的vector<uchar>按字节序写入本地时,出现图片错乱的问题。

调试过程

根据写入文件的vector<uchar>size值,可以发现文件大小要比size的 值大几个字节。初步将问题定位于二进制文件读写出错。

Debug:先写一段读写二进制文件的小程序用于调试。代码如下:

#include <fstream>

using namespace std;

int main()
{
    //定义一个待写入的uchar数组,大小为17
    unsigned char tmpdata[17];
    //初始化数组
    for (size_t i = 0; i < 17; i++)
    {
        tmpdata[i] = i;
    }
    //打开待写入的文件
    std::ofstream ofs("1.jpeg");
    //每次写入一个字节
    for (size_t i = 0; i < 17; i++)
    {
        ofs << tmpdata[i];
    }
    ofs.close();
}

上述代码执行后得到如下结果: 换行符错误 从上图可以看出,在内存地址为00000010处,应该填充0A此处却填充 为0D,导致文件大小为18个字节,与预期不符。

问题成因:0x0A与0x0D分别对应的字符为\n和\r,我们遇到的问题是Windows系统换行为\r\n 导致的,当我们写入0x0A时,系统自动为我们添加上了0x0D,因此上述OpenCV写入图片乱码也同样由于 此问题导致。错误的写入文件方式是导致问题的根源。

解决方案

以二进制模式读写文件,系统就不会自动将0x0A替换为0x0D和0x0A。

关键代码

std::ofstream ofs("1.jpeg",ios::binary);

在添加ios::binary模式后,程序执行与预期相符。

附程序源码:

bool writeVectorToBin(const std::vector<uchar>& img_vec)
{
    std::ofstream ofs("1.jpeg",ios::binary);

    string str_encode(img_vec.begin(), img_vec.end());
    ofs << str_encode;
    ofs.flush();
    ofs.close();
    return true;
}

About

精选博客文章,专注于ASP.NET Core,OpenCV,Windows等领域

Figure

Elsewhere

  1. GitHub
  2. Google
  3. MSDN
© 2021 - AngelNet - Privacy