首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QFile::刷新() vs QFile::close()

QFile::刷新() vs QFile::close()
EN

Stack Overflow用户
提问于 2013-09-30 14:24:45
回答 2查看 15.8K关注 0票数 3

我正在实现类中的一个方法,它将把数据从一个TableView对象写入一个CSV文件。然而,当程序运行时,该程序以非常慢的速度(3或4秒)将数据写入USB驱动器上的文件,但是可以很好地处理系统的内部驱动器。这是因为在编写文件之后,我没有使用刷新()或close()吗?

这是我的密码

代码语言:javascript
复制
bool ThicknessCalibrationDataDisplay::WriteCSVFileChanges()
{
    QModelIndex tableViewModelindex =  tableViewModel_->index(0,0);

    QFile file(CSVFileName_);
    if(!file.exists())
        return false;

    if(!file.open(QIODevice::WriteOnly))
        return false;


    for(int i = 0; i < totalRows_ ; i++)
    {
        for(int j = 0 ; j < totalColumns_; j++)
        {
            tableViewModelindex =  tableViewModel_->index(i,j);
            qDebug()<<tableViewModelindex.data();
            QString text = tableViewModelindex.data().toString();
            QTextStream OutputStream(&file);

            if(j == totalColumns_ - 1)
                OutputStream<<"\n\r";
            else
                OutputStream<<',';

        }
    }

}

这是我之前的代码,现在我计划关闭文件流,以获得一个优雅的退出。QFile::close()的Qt表示

调用QFile::刷新()并关闭该文件。来自刷新的错误将被忽略。

所以,我应该只调用close(),还是调用flush(),记录任何错误,然后调用close()更好呢?

还有什么其他的修改,我必须做,以改善写操作?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-30 14:34:28

  1. flush() is close()是一条红线鲱鱼,它根本不影响你的性能。
  2. QTextStream的销毁会强制刷新文件。冲洗文件很慢。每次迭代循环时,您都在破坏您的文本流!在循环之外创建流! 这是来自QT5.1.1的源代码: QTextStream::~QTextStream() { if (!d->writeBuffer.isEmpty()) d->flushWriteBuffer();} 在QT5.1或更高版本上,如果要确保文件关闭后磁盘缓冲区被刷新,则应该使用QSaveFile。只有这样,您才能保证,一旦您认为您已经完成了保存,数据实际上在磁盘上。
  3. QTextStream有自己的缓冲区。因此,如果您想在刷新时捕获错误,则需要在流本身上使用flush()方法,而不是在QFile上。
  4. 从GUI线程进行任何文件访问都是一个非常糟糕的主意。任何时候,任何情况下,你的UI线程都会阻塞。 现在的问题是:如何使您的模型安全地从另一个线程访问?如果使用自定义模型,则可能只需要在写入文件的过程中将模型切换为只读模式。只读模式将是模型的自定义属性,因此所有setData调用都将失败。当然,您需要向用户表明这一点。模型的视图将是只读的,但这比阻塞整个GUI要友好得多。 如果您认为仅仅防止使用QMutex并发访问模型就足够了,那么请再考虑一下。对模型所做的任何修改都可能会改变其结构,因此您的作者需要正确地处理模型发出的所有信号。这将使作者更加复杂。一个临时的只读模型允许您拥有响应性GUI,同时对用户带来暂时的不便,而代码复杂度的增加是最小的。 类MyModel : public QStandardItemModel /*或任何您从*/ {true继承的类;Q_OBJECT Q_PROPERTY(bool可写读读isWritable写入通知writableChanged) bool m_writable;public:显式MyModel(QObject *父级):继承(父级),m_writable (真) {} Q_SLOT void (){ if (!m_writable)返回;m_writable= false;writableChanged(m_writable);} Q_SLOT void setReadWrite(){ if ( m_writable )返回;m_writable = true;m_writable= writableChanged (m_writable );} Q_SIGNAL void writableChanged( bool );bool isWritable() const {返回m_writable;} void (bool写的){ if (m_writable ==写的)返回;m_writable=写;emit (M_writable);} bool setData(const QModelIndex & index,const QVariant & val,int QVariant= Qt::EditRole) { if (!m_writable)返回false;返回继承的::setData(索引、val、角色);};
  5. 一些USB驱动器速度非常慢。

您的重新编写的代码至少应该如下所示:

代码语言:javascript
复制
bool ThicknessCalibrationDataDisplay::WriteCSVFileChanges()
{
#if QT_VERSION < QT_VERSION_CHECK(5,1,0)
    QFile file(CSVFileName_);
#else
    QSaveFile file(CSVFileName_); // does a disk commit at the end
#endif
    if(!file.exists())
        return false;

    if(!file.open(QIODevice::WriteOnly))
        return false;

    QTextStream os(&file);
    for(int i = 0; i < totalRows_ ; i++)
    {
        for(int j = 0 ; j < totalColumns_; j++)
        {
            QModelIndex index = tableViewModel_->index(i,j);
            qDebug() << index.data();
            os << index.data();
            if(j == totalColumns_ - 1)
                os<<"\n\r";
            else
                os<<',';

        }
    }
    os.flush();
#if QT_VERSION >= QT_VERSION_CHECK(5,1,0)
    return os.status() == QTextStream::Ok && file.commit();
#else
    return os.status() == QTextStream::Ok;
#endif
}
票数 8
EN

Stack Overflow用户

发布于 2013-09-30 14:54:50

我可以告诉您,QFile::close()在函数的末尾被隐式调用,因为QFile对象的析构函数是在文件变量的作用域末尾调用的。来自QFile文档:

代码语言:javascript
复制
QFile::~QFile ()
Destroys the file object, closing it if necessary.

您可能希望尝试的是操作系统的底层同步功能。AFAIK没有为此提供任何API,因此它不会是可移植的。当调用QFile::flush()函数时,一个可能发生的情况(至少在Linux上)是将数据从用户空间缓冲区释放到底层系统缓存,而不一定是磁盘。在linux/unix上,您需要fsync函数来确保文件实际写入磁盘。代码看起来类似于:

代码语言:javascript
复制
file.flush();
fsync( file.handle() );
file.close();

我相信同样的代码也会在Windows上工作。

有关fflush vs fsync的更多信息,请参见Difference between fflush and fsync

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19096702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档