3

次のように、ファイルストリームに1つのバッファを指定できます。

char buf[BUFFER_SIZE];

std::ofstream file("file", std::ios_base::binary | std::ios_base::out);
if (file.is_open())
{
    file.rdbuf()->pubsetbuf(buf, BUFFER_SIZE);
    file << "abcd";
}

私が今やりたいのは、複数のバッファーを使用することです。

char* buf[] = { new char[BUFFER_SIZE], new char[BUFFER_SIZE], new char[BUFFER_SIZE], };

std :: streambufのカスタム派生を作成せずに可能ですか?

編集: 私がやりたいことをもっと詳しく説明する必要があると思います。次の状況を考慮してください。-読み取りたいファイルがメモリに収まらない-ある種のバイナリジャンプ検索によってアクセスされているファイル

したがって、ファイルを特定のサイズの論理ページに分割する場合は、特定のページを表す複数のバッファーを提供したいと思います。これにより、ファイルの場所が読み取られ、関連するページがすでにバッファーにある場合のパフォーマンスが向上します。

4

3 に答える 3

1

ある種のスキャッターギャザーI/Oをやりたいというコメントから集めました。C++標準のI/Oストリームライブラリではサポートされていないことは間違いないので、自分で作成する必要があります。

これを効率的に実行したい場合は、スキャッターギャザーのOSサポートを使用できます。たとえば、POSIX/Unixライクなシステムはwritevこの目的のためにあります。

于 2011-06-09T18:32:04.197 に答える
1

Standardが提供するこのようなものはありません。ただし、プラットフォームによっては、同じ機能を提供するメモリマップトファイルを使用できます。WindowsとLinuxの両方がそれらを提供します。

于 2011-06-10T17:56:52.247 に答える
1

boost :: iostreams :: mapped_fileを見ていきますが、私の要件ははるかに単純だと思います。basic_filebufから派生したカスタムクラスを作成しました。

template<typename char_type>
class basic_filemultibuf : public std::basic_filebuf<char_type/*, std::char_traits<char_type>*/>
{
private:
    char_type**     m_buffers;
    std::ptrdiff_t  m_buffer_count,
                    m_curent_buffer;
    std::streamsize m_buffer_size;

protected:
    virtual int_type overflow(int_type meta = traits_type::eof())
    {
        if (this->m_buffer_count > 0)
        {
            if (this->m_curent_buffer == this->m_buffer_count)
                this->m_curent_buffer = 0;
            this->basic_filebuf::setbuf(this->m_buffers[this->m_curent_buffer++], this->m_buffer_size);
        }

        return this->basic_filebuf::overflow(meta);
    }

public:
    basic_filemultibuf(basic_filebuf const& other)
        : basic_filebuf(other),
          m_buffers(NULL),
          m_buffer_count(0),
          m_curent_buffer(-1),
          m_buffer_size(0)
    {
    }

    basic_filemultibuf(basic_filemultibuf const& other)
        : basic_filebuf(other),
          m_buffers(other.m_buffers),
          m_buffer_count(other.m_buffer_count),
          m_curent_buffer(other.m_curent_buffer),
          m_buffer_size(other.m_buffer_size)
    {
    }

    basic_filemultibuf(FILE* f = NULL)
        : basic_filemultibuf(basic_filebuf(f))
    {
    }

    basic_filemultibuf* pubsetbuf(char** buffers, std::ptrdiff_t buffer_count, std::streamsize buffer_size)
    {
        if ((this->m_buffers = buffers) != NULL)
        {
            this->m_buffer_count  = buffer_count;
            this->m_buffer_size   = buffer_size;
            this->m_curent_buffer = 0;
        }
        else
        {
            this->m_buffer_count  = 0;
            this->m_buffer_size   = 0;
            this->m_curent_buffer = -1;
        }

        this->basic_filebuf::setbuf(NULL, 0);
        return this;
    }
};

使用例:

typedef basic_filemultibuf<char> filemultibuf;

std::fstream file("file", std::ios_base::binary | std::ios_base::in | std::ios_base::out);

char** buffers = new char*[2];
for (int i = 0; i < n; ++i)
    buffers[i] = new char[4096];

filemultibuf multibuf(*file.rdbuf());
multibuf.pubsetbuf(buffers, 2, 4096);
file.set_rdbuf(&multibuf);

//
// do awesome stuff with file ...
//

for (int i = 0; i < n; ++i)
    delete[] buffers[i];

それはほとんどそれです。複数のバッファの使用をfilebufに制限するべきではないため、私が本当にやりたいのは、これを他のstreambufに機能的に提供することだけです。しかし、ファイル固有の関数を書き直さないと不可能だと私には思えます。

あれについてどう思う?

于 2011-06-11T09:32:25.707 に答える