5

所以通常我会做这样的事情:

    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]);

4

1 回答 1

12

以最简单的形式:

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

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

上面可能会做不止一次的内存分配(对于大于很少字节的文件),因为std::istreambuf_iterator<>是输入迭代器,而不是随机访问或前向迭代器,所以文件的长度不能通过减去迭代器 likeend - begin或调用std::distance(begin, end). 如果首先创建向量为空,然后std::vector<>::reserve()调用为文件长度分配内存,最后调用范围插入vec.insert(vec.end(), beg, end)并如上所述读取整个文件begend则可以将其减少为一次内存分配。std::istreambuf_iterator<>

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

使用的原因std::istreambuf_iterator<char>是因为实现使用std::char_traits<>通常只对char和进行专门化wchar_t。无论如何,C 和 C++ 标准要求所有char类型都具有相同的二进制布局,没有填充位,因此和之间char的转换(它们都是不同的类型,不同于并且是相同的类型)保留位模式,因此是安全的。unsigned charsigned charsigned intint

[basic.fundamental/1]

Plain char, signed char, 和unsigned char是三种不同的类型,统称为窄字符类型。A char、 asigned char和 anunsigned char占用相同的存储量,具有相同的对齐要求;也就是说,它们具有相同的对象表示...对于窄字符类型,对象表示的所有位都参与值表示...对于无符号窄字符类型,值表示的每个可能的位模式代表一个不同的数字。这些要求不适用于其他类型。在任何特定的实现中,普通对象可以采用与 a或 anchar相同的值;哪一个是实现定义的。对于每个类型的值signed charunsigned chariunsigned char在 0 到 255 的范围内,存在一个jtype 的值,char使得从 to 的整数转换的结果是 ,从to的整数转换的i结果是。charjjunsigned chari

于 2012-04-26T15:35:55.827 回答