std :: istream意外结束

时间:2019-02-19 12:19:18

标签: c++ stream istream

我正在尝试分块读取二进制文件。该文件约为11 kB。以下代码仅从文件读取一次,gcount()函数表示仅读取1015个字符(字节),并且流“已耗尽”,而while循环不会继续(尽管缓冲区已正确填充,直到buffer[4095]):

std::array<int64_t, 256>  HuffmanTree::get_frequencies(std::istream & stream) const
{
    const size_t buffer_size = 4096;
    unsigned char buffer[buffer_size];
    std::array<int64_t, 256> frequencies;
    frequencies.fill(0);

    while (stream)
    {
        stream.read((char *)buffer, buffer_size);
        std::streamsize bytes_read = stream.gcount();

        for (std::streamsize i = 0; i < bytes_read; i++)
        {
            frequencies[buffer[i]]++;
        }
    }

    return frequencies;
}

是什么原因导致这种现象,我该如何解决?

编辑:stream.read(...)仅被调用一次,gcount()返回1015。但是缓冲区包含文件的前4096字节(我也在Windows-VS 2017上运行)

1 个答案:

答案 0 :(得分:0)

我相信当您要读取的字节少于4096个字节并且您致电stream.read()

时,就会出现问题。

我使用以下函数,该TRIES读取4096,但在失败时会整理-也许有用吗?

// Tries to read num bytes from inRaw into buffer (space previously allocated).  When num bytes does not take
// us off the end of the file, then this does the simple obvious thing and returns true.  When num bytes takes
// us over the edge, but things are still sane (they wanted 100 bytes, only 60 bytes to go), then this fills
// as much as possible and leaves things in a nice clean state.  When there are zero bytes to go, this
// return false.
bool safeRead(
    std::ifstream& inRaw,
    char* buffer,
    uint16_t num
)
{
    auto before = inRaw.tellg();
    if (inRaw.read(buffer, num) && inRaw.good() && !inRaw.eof())
    {
        return true;
    }
    else
    {
        if (inRaw.gcount())
        {
            inRaw.clear();
            auto pos = before + std::streamoff(inRaw.gcount());
            inRaw.seekg(pos);
            return true;
        }
        else
        {
            return false;
        }
    }
}