So normaly I do stuff like:
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();
I wonder how to read into unsigned char
buffer ( boost::shared_array<unsigned char> buffer( new unsigned char[buff_length]);
)
In a simplest form:
Replace
std::cin
with your actual stream.The above is likely to do more than one memory allocation (for files larger than a very few bytes) because
std::istreambuf_iterator<>
is an input-iterator, not a random-access or a forward iterator, so the length of the file can't be measured by subtracting iterators likeend - begin
or callingstd::distance(begin, end)
. It can be reduced to one memory allocation if the vector is created first empty, thenstd::vector<>::reserve()
is called to allocate memory for the file length and finally range insert is calledvec.insert(vec.end(), beg, end)
withbeg
andend
beingstd::istreambuf_iterator<>
as above to read the entire file.If the file size is more then a few kilo-bytes it may be most efficient to map it into the process memory to avoid copying memory from the kernel to user-space.
The reason
std::istreambuf_iterator<char>
is used is because the implementation usesstd::char_traits<>
which normally has specializations only forchar
andwchar_t
. Regardless, the C and C++ standards require allchar
types to have the same binary layout with no padding bits, so conversions betweenchar
,unsigned char
andsigned char
(which are all distinct types, unlikesigned int
andint
being the same type) preserve bit patterns and thus are safe.[basic.fundamental/1]