- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在我的类中实现一个方法,它将数据从 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() 更好?
我是否需要进行任何其他修改以改进写入操作?
最佳答案
flush()
与 close()
是一个转移注意力的问题,它不会影响您的性能根本 .
QTextStream
的销毁会强制刷新文件。刷新文件很慢。每次迭代循环时,您都在破坏文本流!在循环外创建流!
这是来自 Qt 5.1.1 的源代码:
QTextStream::~QTextStream()
{
if (!d->writeBuffer.isEmpty())
d->flushWriteBuffer();
}
在 Qt 5.1 或更新版本上,如果要确保在文件关闭后刷新磁盘缓冲区,则应使用 QSaveFile
。只有这样才能让您确信,一旦您认为已完成保存,数据实际上就在磁盘上。
QTextStream
有自己的缓冲区。所以,如果你想在刷新时捕获错误,你需要在流本身上使用 flush()
方法,而不是在 QFile
上。
从 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);
}
};
一些 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/
在我的一个方法中,我需要一个 QFile 对象: void GUIsubclassKuehniGUI::LoadDirectory() { QString load
我需要将一个 QFile 成 block 地复制到另一个 QFile,所以我不能使用 QFile::copy。这是最原始的实现: bool CFile::copyChunk(int64_t chunk
我正在我的类中实现一个方法,它将数据从 TableView 对象写出到 CSV 文件。然而,当程序运行时,程序以非常慢的速度(3 或 4 秒)将数据写入 USB 驱动器上的文件,但在系统的内部驱动器上
我不知道为什么,但我无法让最简单的 QTemporaryFile 示例运行...我的真正意图是在稍后处理之前将来自 QAudioInput 的数据写入临时文件。 尝试了几次后,我意识到 .read()
我想知道如何 QFile当多个句柄打开到同一个文件时(在 Windows 7 上的 Visual Studio 2013 中使用 C++),我编写了以下小程序: QFile file("tmp.t
当我定义如下结构时出现问题 struct TInputData { QString filename; QFile file; QTextStream
我有一个类(class): Class MyClass { void myMember(); ///code etc private: QFile fileMB
我需要编写一个控制台应用程序来接收一个文件,打开它,然后根据文本文件中的信息调用另一个过程。唯一的问题是 QFile::errorString() 返回: No such file or direct
我编写了以下代码来从文件中检索数据(该文件已经存在并且因为我在 Windows 操作系统上而获得了权限),并创建了项目以在列表中显示数据片段,但该列表不会显示任何内容事物。此外,我发现即使未创建文件,
我有一个名为“sequence_30.dat”的文件,其中包含垂直表示中的 1 和 -1 序列(即:每个 1 或 -1 在单独的行中)..我正在尝试读取文件以获取使用以下代码的另一个操作: int l
是否可以做到以下几点? QFile file("Test.txt") If (file.exists) { //Start writing new data at th
从文件中读取数据并将其保存在 QHash 中,如下所示: QHash > 我的数据文件不包含标题,所以当我第一次创建 vector 然后进入文件循环时,我错过了第一行的数据。我的来源是: Q
我有几个窗口标志为 WindowStaysonTopHint 的对话框。当我打开 QFileDialog 时,它显示在这些对话框的底部。如何为 QFileDialog 设置窗口标志。我使用以下代码在顶
我有一个基本上是从 Qt 网站上窃取的程序,用于尝试打开一个文件。该程序拒绝打开任何我不明白为什么的东西。我已经查找了很多文档,但一无所获,请您解释一下为什么它不起作用。 #include "main
QLabel* codeLabel = new Qlabel; QFile file("C:\index.txt"); file.open(stderr, QIODevice::WriteOnly);
我可以第二次初始化一个QFile并赋值吗?我这样试过 ... QFile file; ... if (i == 0) file = QFile("foo.txt"); else file = QFil
我在 generateCSVHeader(*file4); 处遇到非法间接错误。 函数声明: void generateCSVHeader(QFile * file); 功能使用: str="MyDa
我想知道是否可以一次性创建文件及其目录。例如我想创建文件scripts/myFile.txt。 我写了这样的代码: QFile _file( path ); QDir _dir; // check i
例如: QFile f("/home/umanga/Desktop/image.jpg"); 如何仅获取文件名 - “image.jpg”? 最佳答案 使用 QFileInfo删除路径(如果有): Q
造成这种情况的一些常见原因是什么?我的第一个想法是我正在读取的文件是只读的,但我已经检查过了。 调用它的代码是: QFile histogramFile(fileName); quint64 file
我是一名优秀的程序员,十分优秀!