使用多个ofstreams在c ++中写入单个输出文件

时间:2013-12-24 07:48:39

标签: c++ ofstream streambuf

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

问题

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

2 个答案:

答案 0 :(得分:1)

这不是你想要的吗?这可以很容易地修改为使用ostream而不是ofstreams,这更好 - 实际问题是缓冲区的同步。在这段代码中,我简单地使filebuf bf无缓冲,并且工作正常。或者保持缓冲,但在my_ofstream之间切换时包括对pubsync的调用。我不明白为什么ios:rdbuf不可用。你在创建自己的streambuf吗?

#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;
}   

答案 1 :(得分:1)

这看起来两个类都使用过滤streambuf 成语。无论如何,不​​要从中派生你的类 std::ofstream,但直接来自ostream,并同时拥有它们 使用相同的std::filebuf对象。如果你正在使用 过滤streambuf成语,不要让你的过滤 streambuf的缓冲区;把它留给最后的std::filebuf

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