阅读大文件

时间:2010-11-10 06:36:42

标签: c++ qt qt4

我想读取一个50MB的文件并通过tcp发送。该文件仅包含浮点数。首先我创建了一个Mainwindow,女巫读取一行并将其发送到服务器,但gui被冻结了。所以我创建了一个依赖于QThread的类,叫做QSendThread。这是QThread类的代码:

#ifndef QSENDTHREAD_H
#define QSENDTHREAD_H

#include <QThread>
#include <QLabel>
#include <QFile>
#include <QMessageBox>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QHostAddress>

class QSendThread : public QThread
{
 Q_OBJECT

public:
 QSendThread(QTcpSocket* qtcpso, QLabel* qlbl, QFile* qfiel, QObject *parent = NULL);
 ~QSendThread();

protected:
 void run(void);

private:
 QTcpSocket* qtcpsoDest;
 QLabel* qlblRef;
 QFile* qfileRef;

signals:
 void error(QString qstrError);
};

#endif // QSENDTHREAD_H

#include "qsendthread.h"

QSendThread::QSendThread(QTcpSocket* qtcpso, QLabel* qlbl, QFile* qfile, QObject *parent)
 : QThread(parent)
{
 qtcpsoDest = qtcpso;
 qlblRef = qlbl;
 qfileRef = qfile;
}

QSendThread::~QSendThread()
{
}

void QSendThread::run(void)
{
 int iLine = 0;

 do
 {
  QByteArray qbarrBlock;
  QDataStream qdstrmOut(&qbarrBlock, QIODevice::WriteOnly);

            // show witch line is read
  qlblRef->setText(tr("Reading Line: %1").arg(++iLine));

  qdstrmOut.setVersion(QDataStream::Qt_4_6);
  qdstrmOut << (quint16)0;
  qdstrmOut << qfileRef->readLine().data();
  qdstrmOut.device()->seek(0);
  qdstrmOut << (quint16)(qbarrBlock.size() - sizeof(quint16));

  qtcpsoDest->write(qbarrBlock);
  qtcpsoDest->flush();

  qbarrBlock.clear();
 } while(!qfileRef->atEnd());
}

但是程序在方法qregion::qt_region_strictContains(const QRegion &region, const QRect &rect)

中崩溃了

读取文件的方法是不是我做错了?

感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

首先,您不应该真正需要继承QThread。 Qt文档是misleading on this point。有关很多好消息的类似问题,请参阅此accepted answer

其次,您只能从主线程正确访问gui,因此您的调用qlblRef->setText()将成为问题。可以使用signals and slotspostEvent()从主要线程以外的线程访问gui。您可以阅读事件here

最后,这个documentation实际上是在Qt中处理线程所必需的。请特别注意threads and QObjects上的部分。

<强>增加:

要遵循上面的建议,您当然可以将文件读取代码包装在QObject子类中。另一种选择(我对自己没什么经验)可能是尝试将您的代码放在QtConcurrent::run()中并使用QFuture获得结果。