7

我的班级Writer有两个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();
}

问题

如何确保f2与 同步f1?意思是,在写入之前,流偏移量f2必须与流偏移量同步,f1反之亦然?
我不能使用函数std::ios::rdbuf因为每个都ofstream使用特殊的 derivedstreambuf。所以通过使用rdbuf()我会失去必要的功能。
我尝试使用同步流主题中的一些技术,但无法实现。

4

2 回答 2

1

这不是你要找的吗?这可以很容易地修改为使用 ostreams 而不是 ofstreams,这更好 - 实际问题是缓冲区的同步。在这段代码中,我只是简单地制作了filebuf bf无缓冲的,它工作正常。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

这看起来像您的两个类都使用过滤流缓冲习语。在任何情况下,不要从 派生您的类 std::ofstream,而是直接从派生ostream,并让它们都使用同一个std::filebuf对象。如果你使用的是过滤流缓冲的习语,不要让你的过滤流缓冲缓冲;把它留到最后std::filebuf

换句话说,您的“内部扩展类型的流缓冲区”应该包含一个指向最终接收器的指针,这将是一个filebuf(但您的过滤流缓冲区不需要知道这一点)。像这样的函数sync,它们只是传递到最终目的地,它们永远不应该自己建立缓冲区,而是将所有内容传递给 filebuf。

于 2013-12-24T09:33:06.520 回答