Ответ 1
std::istream
- абстрактный тип – вы не можете использовать его напрямую. Вы должны извлечь из него настраиваемый массив streambuf
:
#include <cstddef>
#include <string>
#include <streambuf>
#include <istream>
template<typename CharT, typename TraitsT = std::char_traits<CharT>>
struct basic_membuf : std::basic_streambuf<CharT, TraitsT> {
basic_membuf(CharT const* const buf, std::size_t const size) {
CharT* const p = const_cast<CharT*>(buf);
this->setg(p, p, p + size);
}
//...
};
template<typename CharT, typename TraitsT = std::char_traits<CharT>>
struct basic_imemstream
: virtual basic_membuf<CharT, TraitsT>, std::basic_istream<CharT, TraitsT> {
basic_imemstream(CharT const* const buf, std::size_t const size)
: basic_membuf(buf, size),
std::basic_istream(static_cast<std::basic_streambuf<CharT, TraitsT>*>(this))
{ }
//...
};
using imemstream = basic_imemstream<char>;
char const* const mmaped_data = /*...*/;
std::size_t const mmap_size = /*...*/;
imemstream s(mmaped_data, mmap_size);
// s now uses the memory mapped data as its underlying buffer.
Что касается самого отображения памяти, я рекомендую использовать Boost.Interprocess для этой цели:
#include <cstddef>
#include <string>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
namespace bip = boost::interprocess;
//...
std::string filename = /*...*/;
bip::file_mapping mapping(filename.c_str(), bip::read_only);
bip::mapped_region mapped_rgn(mapping, bip::read_only);
char const* const mmaped_data = static_cast<char*>(mapped_rgn.get_address());
std::size_t const mmap_size = mapped_rgn.get_size();
Код для imemstream
, взятый из этого Dietmar Kühl.