gpt4 book ai didi

c++ - QFile::flush() 与 QFile::close()

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:15:45 24 4
gpt4 key购买 nike

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

这是我的代码

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 API 说

Calls QFile::flush() and closes the file. Errors from flush are ignored.

那么我应该只调用 close(),还是调用 flush() 记录所有错误然后调用 close() 更好?

我是否需要进行任何其他修改以改进写入操作?

最佳答案

  1. flush()close() 是一个转移注意力的问题,它不会影响您的性能根本 .

  2. QTextStream 的销毁会强制刷新文件。刷新文件很慢。每次迭代循环时,您都在破坏文本流!在循环外创建流!

    这是来自 Qt 5.1.1 的源代码:

    QTextStream::~QTextStream()
    {
    if (!d->writeBuffer.isEmpty())
    d->flushWriteBuffer();
    }

    在 Qt 5.1 或更新版本上,如果要确保在文件关闭后刷新磁盘缓冲区,则应使用 QSaveFile。只有这样才能让您确信,一旦您认为已完成保存,数据实际上就在磁盘上。

  3. QTextStream 有自己的缓冲区。所以,如果你想在刷新时捕获错误,你需要在流本身上使用 flush() 方法,而不是在 QFile 上。

    <
  4. 从 GUI 线程执行任何文件访问是一个非常糟糕的主意。任何时候任何东西阻塞,您的 UI 线程也会阻塞。

    现在的问题是:如何使您的模型可以安全地从另一个线程访问?如果您使用自定义模型,您可能只需要在写入文件期间将模型切换为只读模式。只读模式将是模型的自定义属性,这样所有 setData 调用都会失败。您当然需要向用户表明这一点。模型的 View 将是只读的,但这比阻止整个 GUI 友好得多。

    如果您认为仅使用 QMutex 阻止对模型的并发访问就足够了,请再想一想。对模型所做的任何修改都可能会改变其结构,因此您的作者需要正确处理模型发出的所有信号。这会使作者变得更加复杂。暂时只读的模型让您拥有响应式 GUI,暂时给用户带来不便,同时代码复杂性的增加最少。

    class MyModel : public QStandardItemModel /*  or whatever other class you derive from */ {
    typedef QStandardItemModel inherited;
    Q_OBJECT
    Q_PROPERTY(bool writable READ isWritable WRITE setWritable NOTIFY writableChanged)
    bool m_writable;
    public:
    explicit MyModel(QObject * parent) : inherited(parent), m_writable(true) {}
    Q_SLOT void setReadOnly() {
    if (!m_writable) return;
    m_writable = false;
    emit writableChanged(m_writable);
    }
    Q_SLOT void setReadWrite(){
    if (m_writable) return;
    m_writable = true;
    emit writableChanged(m_writable);
    }
    Q_SIGNAL void writableChanged(bool);
    bool isWritable() const { return m_writable; }
    void setWritable(bool writable) {
    if (m_writable == writable) return;
    m_writable = writable;
    emit writableChanged(m_writable);
    }
    bool setData(const QModelIndex & index, const QVariant & val, int role = Qt::EditRole) {
    if (! m_writable) return false;
    return inherited::setData(index, val, role);
    }
    };
  5. 一些 USB 驱动器非常慢。

您修改后的代码至少应如下所示:

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
}

关于c++ - QFile::flush() 与 QFile::close(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19096702/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com