所以通常我会做这样的事情:
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]);
)
最简单的形式:
std::vector<unsigned char> vec(
std::istreambuf_iterator<char>(std::cin)
, std::istreambuf_iterator<char>()
);
将
std::cin
替换为您的实际流。
上面的代码可能会执行多次内存分配(对于大于几个字节的文件),因为
std::istreambuf_iterator<>
是一个输入迭代器,而不是随机访问或前向迭代器,因此文件的长度可以' t 通过减去 end - begin
等迭代器或调用 std::distance(begin, end)
来测量。如果首先创建空向量,则可以减少到一次内存分配,然后调用 std::vector<>::reserve()
为文件长度分配内存,最后调用范围插入 vec.insert(vec.end(), beg, end)
,其中 beg
和 end
为 std::istreambuf_iterator<>
如上所述读取整个文件。
C++17 标准库可以做到这一点:
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
std::vector<unsigned char> load_file(std::filesystem::path file_path) {
using namespace std;
// Allocate memory for the entire file once.
vector<unsigned char> file_content;
file_content.reserve(file_size(file_path)); // C++17 standard library provides file_size.
// Open the file in binary mode and read its bytes into the vector.
ifstream file_stream(file_path, ios_base::in | ios_base::binary);
file_content.insert(file_content.end(), istreambuf_iterator<char>{file_stream}, {});
return file_content;
}
int main() {
// Load a file.
auto file_content = load_file("/usr/share/doc/gcc/copyright");
// Output file contents into std::cout.
copy(file_content.begin(), file_content.end(), std::ostreambuf_iterator<char>{std::cout});
}
如果文件大小超过几千字节,则将其映射到进程内存中可能是最有效的,以避免将内存从内核复制到用户空间。
使用
std::istreambuf_iterator<char>
的原因是因为实现使用 std::char_traits<>
,通常仅专门针对 char
和 wchar_t
。无论如何,C 和 C++ 标准要求所有 char
类型具有相同的二进制布局,没有填充位,因此 char
、unsigned char
和 signed char
之间的转换(它们都是不同的类型,与 signed int
和int
是同一类型)保留位模式,因此是安全的。
普通
、char
和signed char
是三种不同的类型,统称为 窄字符类型。一个unsigned char
、一个char
、一个signed char
占用相同的存储空间,并且具有相同的对齐要求;也就是说,它们具有相同的对象表示...对于窄字符类型,对象表示的所有位都参与值表示...对于无符号窄字符类型,值表示的每个可能的位模式代表一个不同的数字。这些要求不适用于其他类型。在任何特定的实现中,普通unsigned char
对象可以采用与char
或signed char
相同的值;哪一个是实现定义的。对于 0 到 255(含)范围内的每个unsigned char
类型的值i
,都存在一个unsigned char
类型的值j
,使得从char
到i
的积分转换结果为char
,从j
到j
积分转换的结果是unsigned char
。i