у меня урок 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
и наоборот?
Я не могу использовать функцию станд :: ИОС :: rdbuf так как каждый ofstream
использует специальные производные streambuf
, так с помощью rdbuf()
Я потеряю необходимый функционал.
Я пытался использовать некоторые методы, найденные в Синхронизация потоков тема, но не может сделать это.
Похоже, что оба ваших класса используют фильтрацию streambuf
идиома. В любом случае, не выводите свои уроки из
std::ofstream
, но прямо из ostream
и у них обоих
использовать то же самое std::filebuf
объект. Если вы используете
фильтрация потоковой идиомы, не пусть ваша фильтрация
буфер streambuf; оставить это до финала std::filebuf
,
Другими словами, ваш «внутренний расширенный тип streambuf» должен содержать указатель на конечный приемник, который будет
filebuf
(но ваши фильтрующие потоковые буферы не должны знать
этот). Функции как sync
они просто переходят в финал
пункт назначения, и они никогда не должны устанавливать буфер
сами, но передать все в filebuf.
Разве это не то, что вы ищете? Это может быть легко модифицировано для работы с ostream, а не с ofstream, что лучше — актуальная проблема — синхронизация буферов. В этом коде я просто сделал filebuf bf
небуферизованный и работает нормально. Или оставьте его в буфере, но включите звонки pubsync
при переключении между my_ofstream’s. Я не понимаю почему 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;
}