[Interest] QTextStream doesn't write to QFile

Koehne Kai Kai.Koehne at theqtcompany.com
Fri Jan 16 12:44:08 CET 2015



> -----Original Message-----
> From: interest-bounces+kai.koehne=theqtcompany.com at qt-project.org
> [mailto:interest-bounces+kai.koehne=theqtcompany.com at qt-project.org]
> On Behalf Of Igor Mironchik
> Sent: Friday, January 16, 2015 12:24 PM
> To: interest at qt-project.org
> Subject: [Interest] QTextStream doesn't write to QFile
> 
> Hi. I'm doing a simple log class. I'm sure that Log creates after
> QCoreApplication.
> QCoreApplication is static. I create QCoreApplication as:
> 
> static QSharedPointer< QCoreApplication > application(
> 	int argc = 0, char ** argv = 0 )
> {
> 	static QSharedPointer< QCoreApplication > app(
> 		new QCoreApplication( argc, argv ) );
> 
> 	return app;
> }

It seems you're desperately trying here to extend QCoreApplications lifetime as long as possible. This is just asking for trouble: just let QCoreApplication be destructed when your application exits, in main.cpp.

> But this Log doesn't write anything to the file. File creates, I'm sure in it. But
> nothing writes. What is the reason?

Log is again declared as a static object, so the destructor runs when the app is already unloading: This might be just too late to write stuff with QFile.

Instead, I'd use qAddPostRoutine or QCoreApplication::aboutToQuit() to close the log file ... or just flush the file after every access: This involves of course some overhead, but if your app crashes before exiting you have at least some logging data :)

Regards

Kai


> And another problem is that QFile in destructor crashes application. Why?
> 
> -------------------------------------------
> //! Severity
> enum Severity {
> 	//! Info.
> 	Info = 0,
> 	//! Warning.
> 	Warning = 1,
> 	//! Error.
> 	Error = 2,
> 	//! Critical.
> 	Critical = 3
> }; // enum Severity
> 
> //
> // Log
> //
> 
> class LogPrivate;
> 
> //! Log.
> class Log {
> public:
> 	static Log & instance();
> 
> 	Log & operator [] ( Severity s );
> 
> 	Log & operator << ( const QString & data );
> 	Log & operator << ( const char * data );
> 
> private:
> 	Log();
> 	~Log();
> 
> private:
> 	Q_DISABLE_COPY( Log )
> 
> 	QScopedPointer< LogPrivate > d;
> }; // class Log
> 
> #define LOG( S ) Log::instance()[ S ]
> -------------------------------------------
> 
> And here is implementation:
> 
> -------------------------------------------
> //
> // LogPrivate
> //
> 
> class LogPrivate {
> public:
> 	LogPrivate()
> 		:	severity( Info )
> 	{
> 		stream.setCodec( QTextCodec::codecForName( "UTF-8" ) );
> 	}
> 
> 	~LogPrivate()
> 	{
> 		stream.flush();
> 
> 		if( file.isOpen() ) // HERE APPLICATION CRASHES !!!
> 			file.close();	}
> 
> 	void initLogFile( const QDate & d )
> 	{
> 		if( date != d )
> 		{
> 			stream.flush();
> 
> 			if( file.isOpen() )
> 				file.close();
> 
> 			file.setFileName( QLatin1String( "./log/test." ) +
> 				d.toString( QLatin1String( "yy.MM.dd" ) ) +
> 				QLatin1String( ".log" ) );
> 			file.open( QIODevice::WriteOnly |
> QIODevice::Append );
> 
> 			stream.setDevice( &file );
> 
> 			date = d;
> 		}
> 	}
> 
> 	QString severityToString() const
> 	{
> 		switch( severity )
> 		{
> 			case Info :
> 				return QLatin1String( "info" );
> 
> 			case Warning :
> 				return QLatin1String( "warning" );
> 
> 			case Error :
> 				return QLatin1String( "error" );
> 
> 			case Critical :
> 				return QLatin1String( "critical" );
> 
> 			default :
> 				return QString();
> 		}
> 	}
> 
> 	//! Severity.
> 	Severity severity;
> 	//! Stream.
> 	QTextStream stream;
> 	//! File.
> 	QFile file;
> 	//! Date.
> 	QDate date;
> }; // class LogPrivate
> 
> 
> //
> // Log
> //
> 
> Log &
> Log::instance()
> {
> 	static Log log;
> 
> 	return log;
> }
> 
> Log &
> Log::operator [] ( Severity s )
> {
> 	d->severity = s;
> 
> 	d->initLogFile( QDate::currentDate() );
> 
> 	d->stream << "\n" << "[" << QTime::currentTime().toString(
> QLatin1String( "hh:mm:ss" ) )
> 		<< "] [" << d->severityToString() << "] ";
> 
> 	d->severity = Info;
> 
> 	return *this;
> }
> 
> Log &
> Log::operator << ( const QString & data ) {
> 	d->stream << data;
> 
> 	return *this;
> }
> 
> Log &
> Log::operator << ( const char * data )
> {
> 	Log::operator << ( QString( data ) );
> 
> 	return *this;
> }
> 
> Log::Log()
> 	:	d( new LogPrivate )
> {
> }
> 
> Log::~Log()
> {
> }
> -------------------------------------------
> 
> 
> --
> Best Regards,
> Igor Mironchik.
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest



More information about the Interest mailing list