PDA

View Full Version : How to use QtConcurrent on QByteArray for parallelize qCompress



JohnJohn
29th April 2015, 15:28
Hi all,
Firstly being new on this forum, i quickly present myself. My Name is John, i'm 25 and i'm a french student to an IT engineering school.
I'm currently trying to develop a simple QT C++ 11 program to compress all files contained into a directory.
I want to use qCompress from QByteArray class to do this trick.

I got to do it in a single threaded environment, so now i want to compress in a multi threaded environment by using QtConcurrent.

But i have no idea on how to do it properly.

Here a draft i written :



QFile outFile("testCompress.ecf");
outFile.open(QIODevice::WriteOnly);
QByteArray nonCompressedData;
foreach(const QString &file,future.results()){
//Fichier d'entrée
QFile inFile(file);
inFile.open(QIODevice::ReadOnly);
nonCompressedData.append(inFile.readAll());
inFile.close();
text += file + "\n";
}

//QByteArray compressedData(qCompress(nonCompressedData,9));
//PROBLEM HERE
QFuture<QByteArray> futureCompressor = QtConcurrent::filtered(nonCompressedData,qCompress );
futureCompressor.waitForFinished();
QByteArray compressedData = futureCompressor.results();

outFile.write(compressedData);


But i have some compilation errors.

I think it is a bad way to do this so i need some help to go on the right way.

Compilations errors :

First : No matching function for call to filtered(&QByteArray,).

Second : converstion from QList to non scalar type QByteArray requested.

Thanks in advance

wysota
29th April 2015, 15:35
Hi John,

You should use the "map" and not "filter" semantics. For a vector of file names you should receive a vector of byte arrays containing compressed data from subsequent files.

JohnJohn
29th April 2015, 15:37
Okay, thank you for the quick reply.

I need to understand why to use map instead of filter?

wysota
29th April 2015, 15:43
Map converts one data (file name) into other data (compressed content). Filter creates a subset of original data matching certain criteria. In your case it could return file names of files containing images.

JohnJohn
29th April 2015, 16:03
Ok thank you.

I will try this with mapped.

Just another advice, to make sure i really understand the philosophy.

I have to store into a Vector of QByteArray all the files name non compressed, and call map by passing the vector and qCompress method?

Added after 7 minutes:

Maybe i will have to use a lambda function to wrap qCompress ?

wysota
29th April 2015, 17:31
I have to store into a Vector of QByteArray all the files name non compressed, and call map by passing the vector and qCompress method?

It has to be a function taking a file name, opening the file, reading it, compressing and returning the content. qCompress() doesn't do all that.

An example function (ignoring memory restrictions) could be:


QByteArray compressFile(const QString &fileName) {
QFile f(fileName);
if(!f.open(QFile::ReadOnly)) return QByteArray();
return qCompress(f.readAll());
}