PDA

View Full Version : QFile::resize takes forever and freezes the GUI



MaximA
27th May 2008, 00:06
QFile::resize takes forever for a 300MB file

I know, that QFile::resize() writes 0x00 on every position and might need that long, that's the reason, why I have put it into a QThread, but still all action halts until it is ready.
(I init the QThread in the main-window constructor, maybe that's wrong?)

Also because it is not necessary to initialize the file with 0x00s, is there a way just to allocate the file-space without initializing (that should be totally fast)?

Thanks

(using: QT4.3 mingw XP)

PS: how can I edit a thread-title to "[solved]..." if its solved?

ChristianEhrlicher
27th May 2008, 06:48
When your main-thread stalls you did not create a new thread/did not start it. I suggest rerading the Documentation about QThread (http://doc.trolltech.com/4.3/qthread.html) carefully.
The only way to resize without setting bytes to 0 is to not use Qt here.

MaximA
27th May 2008, 08:01
Hi Christian,
thanks for answering


MyMain::MyMain()
{
...
fileThread= new MyFileThread(this);
fileThread->start();
}

void MyFileThread::run()
{
exec();
}



the fileThread->isRunning() returns true, and the QTimer in fileThread starting the resize, works too.

I'm almost going to rewrite the QFile::resize with inserted qApp->processEvent() (don't know yet if it would be secure enough)


The only way to resize without setting bytes to 0 is to not use Qt here.
That sounds good, but could you please help me here, because I couldn't find an example how to do it, everywhere I looked, it is initialized with some value. (any link or code snippet would be highly appreciated)

Thanks

ChristianEhrlicher
27th May 2008, 08:11
Looks fine - and where do you do the actual resize?

A WInAPI function to use is SetFilePointer() but you should remember that it's winapi and not protable. Also winapi isn't that easy for beginners.

MaximA
27th May 2008, 08:31
MyFileThread::MyFileThread(QObject * parent ) : QThread(parent)
{
setPriority(QThread::LowestPriority);
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(save()));
timer->start(60000);
}

void MyFileThread::save()
{
timer->stop();
QFile file("test.dat");
resizeSuccess = file.resize(data->files_info->size);
}

I just tried it again (with fileThread= new MyFileThread()<-without the parent);, and it still stalls the gui until it's done resizing.


A WInAPI function to use is SetFilePointer() but you should remember that it's winapi and not protable. Also winapi isn't that easy for beginners.
I have never used winapi so it would be a new realm ..sigh..:) but I will look it up
I've read there is also a possibility doing something similar in the ext3-linux filesystem
(but it will be primarily for win-xp)
thanks

ChristianEhrlicher
27th May 2008, 08:33
You use QThread wrong. The connect is done in the main thread and since it's a direct connection, the resize will also be done in the main thread and therefore the GUI is stalled.

MaximA
27th May 2008, 08:55
Okay, so I have to put the connect here?


void MyFileThread::run()
{
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(save()));
timer->start(60000);
}

that doesn't work either - I have no clue..sigh..

ChristianEhrlicher
27th May 2008, 09:02
This should work - now QTimer is also in the thread. Plz also ready Qt::ConnectionType (http://doc.trolltech.com/4.3/qt.html#ConnectionType-enum) Documentation.

btw: Why not use QTimer::singleShot() ?

MaximA
27th May 2008, 09:53
Thanks, I have some serious reading and recoding to do ('cause it's still not working)
(Threads aren't trivial :) )

the timer will later be used repeatedly for different files

I come back later, after some "homework" :)

Have a nice day.