7

Writer私は2人のメンバーを持つクラスを持っていofstreamます。両方のストリームが同じ出力ファイル
に関連付けられています。メソッドで両方のストリームを使用したいのですが、各ストリームが実際の出力ファイルの最後に書き込むようにします。Writer::write

コード

class my_ofstream1:
    public ofstream
{
    // implement some functions.
    // using internal, extended type of streambuf
};

class my_ofstream2:
    public ofstream
{
    // implement some functions.
    // using internal, extended type of streambuf 
    // (not the same type as found in my_ofstream1)
};


class Writer
{
public:

    void open(string path)
    {
        f1.open(path.c_str(),ios_base::out); f2.open(path.c_str(),ios_base::out);
    }

    void close()
    {
        f1.close(); f2.close();
    }

    void write()
    {
        string s1 = "some string 1";
        string s2 = "some string 2";
        f1.write(s1.c_str(), s1.size());

        // TBD - ensure stream f2 writes to the end of the actual output file
        assert(f1.tellp() == f2.tellp());
        f2.write(s2.c_str(), s2.size());
    }

private:
    my_ofstream1 f1;
    my_ofstream1 f2;
};

void main()
{
    Writer w;
    w.open("some_file.txt");
    w.write();
    w.close();
}

質問と同期している

ことを確認するにはどうすればよいですか? つまり、書き込む前に、 のストリーム オフセットは のストリーム オフセットと同期している必要があります。それぞれが特別な派生を使用する 関数std::ios::rdbufを使用できません。使用すると、必要な機能が失われます。Synchronizing Streamsトピック にあるいくつかの手法を使用してみましたが、実現できませんでした。f2f1f2f1
ofstreamstreambufrdbuf()

4

2 に答える 2

1

これはあなたが探しているものではありませんか?これは、ofstreams ではなく ostreams で動作するように簡単に変更できます。これはより優れています。実際の問題は、バッファーの同期です。このコードでは、単純にfilebuf bfunbuffered を作成しただけで、正常に動作します。または、バッファリングしたままにしてpubsync、my_ofstream を切り替えるときにへの呼び出しを含めます。利用できない理由がわかりios:rdbufません。独自のストリームバッファを作成していますか?

#include <iostream>
#include <fstream>
#include <assert.h>

using namespace std;

class my_ofstream1 : public ofstream
{
public:
    my_ofstream1& write (const char_type* s, streamsize n)
    {
        ofstream::write (s, n);
        //rdbuf()->pubsync();
        return *this;
    }

    void attach (filebuf* bf){
        ios::rdbuf(bf);
    }
};

class my_ofstream2 : public ofstream
{
public:
    my_ofstream2& write (const char_type* s, streamsize n)
    {
        ofstream::write (s, n);
        //rdbuf()->pubsync();
        return *this;
    }

    void attach (filebuf* bf){
        ios::rdbuf(bf);
    }
};


class Writer
{
    filebuf bf;
    my_ofstream1 f1;
    my_ofstream1 f2;

public:

    void open(string path)
    {
        bf.open(path.c_str(),ios_base::out);
        bf.pubsetbuf(0,0); //unbufferred
        f1.attach(&bf); f2.attach(&bf);
    }

    void close()
    {
        f1.close(); f2.close();
    }

    void write()
    {
        string s1 = "some string 1";
        string s2 = "some string 2";
        f1.write(s1.c_str(), s1.size());

        assert(f1.tellp() == f2.tellp());
        f2.write(s2.c_str(), s2.size());
    }


};

int main()
{
    Writer w;
    w.open("some_file.txt");
    w.write();
    w.close();

    return 0;
}   
于 2013-12-24T09:32:33.800 に答える
1

これは、両方のクラスがフィルタリング streambuf イディオムを使用しているようです。いずれにせよ、クラスを から std::ofstreamではなく から直接派生ostreamさせ、両方で同じstd::filebufオブジェクトを使用するようにします。フィルタリング streambuf イディオムを使用している場合は、フィルタリング streambuf のバッファを許可しないでください。それは最後までお任せstd::filebufください。

つまり、「内部の拡張型 streambuf」には、最終的なシンクへのポインタが含まれているfilebuf必要があります (ただし、フィルタリングする streambuf はこれを知る必要はありません)。のような関数はsync、最終的な宛先に渡すだけであり、バッファー自体を確立することはありませんが、すべてを filebuf に渡します。

于 2013-12-24T09:33:06.520 に答える