Istream vs memory mapping file?

Я пытаюсь отобразить файл в память, а затем проанализировать строку по строке - istream, что я должен использовать?

Является ли istream таким же, как отображение файла в память на окнах? У меня возникли трудности с поиском полного примера отображения файла в память.

Я видел, как люди ссылаются на статьи сопоставления памяти из msdn, но если кто-нибудь может порекомендовать небольшой (~ 15 строк?) пример, я был бы очень желанным.

Я должен искать неправильную вещь, но при поиске примера сопоставления памяти С++ в google я не смог найти пример, который включал итерацию.

Это были самые близкие результаты (просто люди поняли, что я посмотрел): http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2044.html#ClassSharedMemoryObjectExample

http://msdn.microsoft.com/en-us/library/dd997372.aspx (нет кода на С++)

http://beej.us/guide/bgipc/output/html/multipage/mmap.html (для Unix я верю, а не из окон)

Ответ 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.

Ответ 2

Является ли istream таким же, как отображение файла в память на окнах?

Не совсем. Они не совпадают в том же смысле, что "поток" не является "файлом".

Подумайте о файле как о сохраненной последовательности и о потоке в качестве интерфейса для "канала" (stream_buffer), который последовательность перемещается при перемещении из своего хранилища в сторону принимающих переменных.

Подумайте о файле с отображением памяти в виде "файла", который вместо того, чтобы храниться вне модуля обработки, хранится в синхронизации в памяти. Преимущество состоит в том, чтобы быть видимым в качестве необработанного буфера памяти, являющегося файлом. Если вы хотите прочитать его как поток, самым простым способом, вероятно, является использование istringstream, у которого этот необработанный буфер является местом для чтения.