13

ファイルをメモリにマップし、行ごとに解析しようとしています。istream を使用する必要がありますか?

istream は、Windows でファイルをメモリにマッピングすることと同じですか? ファイルをメモリにマッピングする完全な例を見つけるのに苦労しました。

私は人々が MSDN からメモリ マッピングの記事にリンクしているのを見てきました。

私は間違ったことを探しているに違いありませんが、Google で「C++ メモリ マッピングの例」を検索すると、反復処理を含む例が見つかりませんでした。

これらは最も近い結果でした (人々が私見たことに気付くように):

4

3 に答える 3

14

std::istreamは抽象型です。直接使用することはできません。カスタムの array-backed を使用して、それから派生する必要があります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();

Dietmar Kühlによるこの回答imemstreamから取得したコード。

于 2012-05-31T19:11:55.627 に答える
1

istream は Windows でファイルをメモリにマッピングすることと同じですか?

ではない正確に。「ストリーム」は「ファイル」ではないという意味で、それらは同じではありません。

ファイルを格納されたシーケンスと考え、ストリームを「チャネル」(stream_buffer) のインターフェイスと考えてください。そのシーケンスは、そのストアから受信変数に向かって移動するときに流れます。

メモリにマップされたファイルを、代わりに処理ユニットの外部に保存された「ファイル」がメモリに同期して保存されていると考えてください。ファイルである生のメモリバッファとして見えるという利点があります。ストリームとして読み取りたい場合、最も簡単な方法はおそらく、読み取り元としてその生のバッファーを持つ istringstream を使用することです。

于 2012-05-31T19:22:07.110 に答える