Я ищу реализацию std::ostream
, которая действует как /dev/null
. Он просто проигнорировал бы все, что было передано ему. Существует ли такая вещь в стандартных библиотеках или Boost? Или мне нужно катиться самостоятельно?
Есть ли реализация null std:: ostream в С++ или библиотеках?
Ответ 1
Если у вас есть boost, тогда существует реализация null ostream и istream, доступная в boost/iostreams/device/null.hpp. Суть его:
#include "boost/iostreams/stream.hpp"
#include "boost/iostreams/device/null.hpp"
...
boost::iostreams::stream< boost::iostreams::null_sink > nullOstream( ( boost::iostreams::null_sink() ) );
...
Ответ 2
Самое простое решение - просто использовать нераспечатанный std::ofstream
. Эта
приведет к возникновению состояния ошибки в потоке, но большинство выходов не будут
Проверь это; обычная идиома заключается в том, чтобы оставить чек до конца, после
закрыть (что бы вы указали в коде, который вы написали, где вы знаете, что
поток должен быть недействительным).
В противном случае это довольно просто реализовать: просто создайте
streambuf
, который содержит небольшой буфер и устанавливает его в overflow
(всегда возвращающий успех). Обратите внимание, что это будет медленнее, чем
нераспечатанный файл; различные операторы >>
все равно будут
преобразование (которое они не делают, если поток имеет состояние ошибки).
EDIT:
class NulStreambuf : public std::streambuf
{
char dummyBuffer[ 64 ];
protected:
virtual int overflow( int c )
{
setp( dummyBuffer, dummyBuffer + sizeof( dummyBuffer ) );
return (c == traits_type::eof()) ? '\0' : c;
}
};
Обычно для обеспечения класса удобства, полученного из istream
или ostream
, который будет содержать экземпляр этого
который он использует. Что-то вроде:
class NulOStream : private NulStreambuf, public std::ostream
{
public:
NulOStream() : std::ostream( this ) {}
NulStreambuf* rdbuf() const { return this; }
};
Или вы можете просто использовать std::ostream
, передав адрес
streambuf к нему.
Ответ 3
Если вы установите badbit
в потоке, он ничего не выведет:
#include <iostream>
int main() {
std::cout << "a\n";
std::cout.setstate(std::ios_base::badbit);
std::cout << "b\n";
std::cout.clear();
std::cout << "c\n";
}
Выходы:
a
c
Ответ 4
Я знаю, что это очень старая тема, но я хотел бы добавить это всем, кто ищет такое же решение без ускорения и быстрого.
Выше я объединил три разных предложения и одно письмо непосредственно в /dev/null (так что это касается ядра.)
Удивительно, но NullStream, получивший наибольшее количество голосов, показал худшие результаты.
Вот результаты для 100 000 000 записей:
a) /dev/null : 30 seconds
b) NullStream: 50 seconds
c) badbit : 16 seconds (the winner in speed, but cannot test for errors!)
d) boost : 25 seconds (the ultimate winner)
Вот тестовый код
#include <iostream>
#include <fstream>
#include <time.h>
#include <boost/iostreams/stream.hpp>
class NullStream : public std::ostream {
class NullBuffer : public std::streambuf {
public:
int overflow( int c ) { return c; }
} m_nb;
public:
NullStream() : std::ostream( &m_nb ) {}
};
int test( std::ostream& ofs, const char* who ) {
const time_t t = time(NULL);
for ( int i = 0 ; i < 1000000000 ; i++ )
ofs << "Say the same" ;
std::cout << who << ": " << time(NULL) - t << std::endl;
}
void devnull() {
std::ofstream ofs;
ofs.open( "/dev/null", std::ofstream::out | std::ofstream::app );
test(ofs, __FUNCTION__);
ofs.close();
}
void nullstream() {
NullStream ofs;
test(ofs, __FUNCTION__);
}
void badbit() {
std::ofstream ofs;
ofs.setstate(std::ios_base::badbit);
test(ofs, __FUNCTION__);
}
void boostnull() {
boost::iostreams::stream< boost::iostreams::null_sink > nullOstream( ( boost::iostreams::null_sink() ) );
test(nullOstream, __FUNCTION__);
}
int main() {
devnull();
nullstream();
badbit();
boostnull();
return 0;
}
РЕДАКТИРОВАТЬ
Самое быстрое решение - где мы используем бадбит - имеет обратную сторону. Если программа проверяет, успешно ли записан вывод - и я понятия не имею, почему программа не должна этого делать, - то из-за этого бадбита произойдет сбой. Поэтому, занявший второе место - повышение - это победитель.
Ответ 5
Для меня самый простой способ был бы:
#include <fstream>
std::ostream* out = &std::cout;
std::ostream* nullstream() {
static std::ofstream os;
if (!os.is_open())
os.open("/dev/null", std::ofstream::out | std::ofstream::app);
return &os;
}
int main() {
*out << "Normal output\n";
out = nullstream();
*out << "Will not visible\n";
out = &std::cout;
*out << "Back again\n";
return 0;
}
Или используйте флаг "badbit" вместо "/dev/null" в функции "nullstream", как описано выше.
std::ostream* nullstream() {
static std::ofstream os;
static bool flag_set = false;
if (!flag_set) {
os.setstate(std::ios_base::badbit);
flag_set = true;
}
return &os;
}
Ответ 6
Пусть это решение преодолевает проблему производительности без использования повышения:
#include <ostream>
class dev0_buffer : public std::streambuf
{
//called usually for n-characters
std::streamsize xsputn (const char* s, std::streamsize n) override { return n; }
//may not required due it not called anymore
int overflow (int c) override { return c; }
} nirwana;
class dev0_stream : public std::ostream
{
public:
dev0_stream(): std::ostream(&nirwana){}
};