【问题标题】:Getting wrong data back when reading from binary file从二进制文件读取时返回错误数据
【发布时间】:2015-07-29 21:12:47
【问题描述】:

我在读取 yuv 文件的某些字节时遇到问题(如果重要的话,它是 1280x720),我希望有人能指出我做错了什么。我使用 read 命令和使用 istream iterator 得到不同的结果。这是我正在尝试做的一些示例代码:

void readBlock(std::ifstream& yuvFile, YUVBlock& destBlock, YUVConfig& config, const unsigned int x, const unsigned int y, const bool useAligned = false)
{
    //Calculate luma offset
    unsigned int YOffset = (useAligned ? config.m_alignedYFileOffset : config.m_YFileOffset) +
    (destBlock.yY * (useAligned ? config.m_alignedYUVWidth : config.m_YUVWidth) + destBlock.yX);// *config.m_bitDepth;

//Copy Luma data
//yuvFile.seekg(YOffset, std::istream::beg);
    for (unsigned int lumaY = 0; lumaY < destBlock.m_YHeight && ((lumaY + destBlock.yY) < config.m_YUVHeight); ++lumaY)
    {
        yuvFile.seekg(YOffset + ((useAligned ? config.m_alignedYUVWidth : config.m_YUVWidth)/* * config.m_bitDepth*/) * (lumaY), std::istream::beg);
        int copySize = destBlock.m_YWidth;
        if (destBlock.yX + copySize > config.m_YUVWidth)
        {
            copySize = config.m_YUVWidth - destBlock.yX;
        }
        if (destBlock.yX >= 1088 && destBlock.yY >= 704)
        {
            char* test = new char[9];
            yuvFile.read(test, 9);

            delete[] test;
            yuvFile.seekg(YOffset + ((useAligned ? config.m_alignedYUVWidth : config.m_YUVWidth)/* * config.m_bitDepth*/) * (lumaY));
        }

        std::istream_iterator<uint8_t> start = std::istream_iterator<uint8_t>(yuvFile);
        std::copy_n(start, copySize, std::back_inserter(destBlock.m_yData));

    }
}
struct YUVBlock
{
std::vector<uint8_t> m_yData;
std::vector<uint8_t> m_uData;
std::vector<uint8_t> m_vData;
unsigned int m_YWidth;
unsigned int m_YHeight;
unsigned int m_UWidth;
unsigned int m_UHeight;
unsigned int m_VWidth;
unsigned int m_VHeight;

unsigned int yX;
unsigned int yY;
unsigned int uX;
unsigned int uY;
unsigned int vX;
unsigned int vY;
};

此错误似乎仅发生在图像中的 X = 1088 和 Y = 704 处。我希望看到一个字节值 10 作为我读回的第一个字节。当我使用

yuvFile.read(test, 9);

我得到 10 作为我的第一个字节。当我使用 istream 迭代器时:

std::istream_iterator<uint8_t> start = std::istream_iterator<uint8_t>(yuvFile);
    std::copy_n(start, copySize, std::back_inserter(destBlock.m_yData));

我读取的第一个字节是 17。17 是 10 之后的字节,所以 istream 迭代器似乎跳过了第一个字节。

任何帮助将不胜感激

【问题讨论】:

  • 1.确保您的文件以std::ios::binary 模式打开。 2. 使用std::istreambuf_iterator。我怀疑您的 10 被作为文本模式换行符跳过 (see this chart)。
  • 啊,是的,你可能是对的。不过,我不能让我的 istreambuf_iterator 接收我的 istream。我应该能够做到这一点,不是吗? std::copy_n((std::istreambuf_iterator&lt;uint8_t&gt;(yuvFile)), copySize, std::back_inserter(destBlock.m_yData));

标签: c++ io istream


【解决方案1】:

istream::readstd::istream_iterator 之间有一个主要区别。

std::istream::read 执行无格式读取。
std::istream_iterator 执行格式化读取。

来自http://en.cppreference.com/w/cpp/iterator/istream_iterator

std::istream_iterator 是一个单通道输入迭代器,它通过调用适当的operator&gt;&gt; 从构造它的std::basic_istream 对象中读取T 类型的连续对象。

如果您的文件是使用std::ostream::writefwrite 创建的,则必须使用std::istream::readfread 来读取数据。

如果您的文件是使用任何创建格式化输出的方法创建的,例如std::ostream::operato&lt;&lt;()fprintf,您就有机会使用std::istream_iterator 读取数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 2015-06-27
    • 2015-04-23
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多