如何从std :: ifstream将文件读入unsigned char数组?

时间:2012-04-26 14:11:39

标签: c++ boost std boost-iostreams

所以我做了类似的事情:

    std::ifstream stream;
    int buff_length = 8192;
    boost::shared_array<char> buffer( new char[buff_length]);
    stream.open( path.string().c_str(), std::ios_base::binary);
    while (stream)
    {
            stream.read(buffer.get(), buff_length);
            //boost::asio::write(*socket, boost::asio::buffer(buffer.get(), stream.gcount()));
    }
    stream.close();

我想知道如何阅读unsigned char缓冲区(boost::shared_array<unsigned char> buffer( new unsigned char[buff_length]);

1 个答案:

答案 0 :(得分:11)

以最简单的形式:

std::vector<unsigned char> vec(
      std::istreambuf_iterator<char>(std::cin)
    , std::istreambuf_iterator<char>()
    );

std::cin替换为您的实际流。

以上内容可能会进行多次内存分配(对于大于极少数字节的文件),因为std::istreambuf_iterator<>是输入迭代器,而不是随机访问或前向迭代器,因此长度为无法通过减去end - begin或调用std::distance(begin, end)等迭代器来测量文件。如果向量首先创建为空,则可以减少为一个内存分配,然后调用std::vector<>::reserve()为文件长度分配内存,最后使用vec.insert(vec.end(), beg, end)和{beg调用范围插入{1}}如上所述end来阅读整个文件。

如果文件大小超过几千字节,将它映射到进程内存可能是最有效的,以避免将内存从内核复制到用户空间。

使用std::istreambuf_iterator<>的原因是因为该实现使用的std::istreambuf_iterator<char>通常只对std::char_traits<>char具有特化。无论如何,C和C ++标准要求所有wchar_t类型具有相同的二进制布局而没有填充位,因此charcharunsigned char之间的转换(均为不同的类型,不同于signed charsigned int是相同的类型)保留位模式,因此是安全的。

[basic.fundamental/1]

  

普通intcharsigned char是三种不同的类型,统称为窄字符类型unsigned charcharsigned char占用相同数量的存储空间并具有相同的对齐要求;也就是说,它们具有相同的对象表示...对于窄字符类型,对象表示的所有位都参与值表示...对于无符号窄字符类型,值表示的每个可能位模式表示不同的数字。这些要求不适用于其他类型。在任何特定实现中,普通unsigned char对象可以采用与charsigned char相同的值;哪一个是实现定义的。对于0到255(包括0和255)范围内类型unsigned char的每个值i,存在unsigned char类型的值j,以便从{{转换为整数转换的结果1}}到chari,从charj的整数转换结果为j