Copy directory using Qt - qt

I want to copy a directory from one drive to another drive. My selected directory contains many sub directories and files.
How can I implement the same using Qt?

void copyPath(QString src, QString dst)
{
QDir dir(src);
if (! dir.exists())
return;
foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
QString dst_path = dst + QDir::separator() + d;
dir.mkpath(dst_path);
copyPath(src+ QDir::separator() + d, dst_path);
}
foreach (QString f, dir.entryList(QDir::Files)) {
QFile::copy(src + QDir::separator() + f, dst + QDir::separator() + f);
}
}

Manually, you can do the next things:
1). with func below you generate folders/files list (recursively) - the destination files.
static void recurseAddDir(QDir d, QStringList & list) {
QStringList qsl = d.entryList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
foreach (QString file, qsl) {
QFileInfo finfo(QString("%1/%2").arg(d.path()).arg(file));
if (finfo.isSymLink())
return;
if (finfo.isDir()) {
QString dirname = finfo.fileName();
QDir sd(finfo.filePath());
recurseAddDir(sd, list);
} else
list << QDir::toNativeSeparators(finfo.filePath());
}
}
2). then you may to start copying files from destination list to the new source directory like that:
for (int i = 0; i < gtdStringList.count(); i++) {
progressDialog.setValue(i);
progressDialog.setLabelText(tr("%1 Coping file number %2 of %3 ")
.arg((conf->isConsole) ? tr("Making copy of the Alta-GTD\n") : "")
.arg(i + 1)
.arg(gtdStringList.count()));
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
if (progressDialog.wasCanceled()) {
// removing tmp files/folders
rmDirectoryRecursive(tmpFolder);
rmDirectoryRecursive(tmpFolderPlus);
setEnableGUI(true);
return;
}
// coping
if (!QFile::copy(gtdStringList.at(i), tmpStringList.at(i))) {
if (warningFlag) {
QMessageBox box(this);
QString name = tr("Question");
QString file1 = getShortName(gtdStringList.at(i), QString("\\...\\"));
QString file2 = getShortName(tmpStringList.at(i), QString("\\...\\"));
QString text = tr("Cannot copy <b>%1</b> <p>to <b>%2</b>" \
"<p>This file will be ignored, just press <b>Yes</b> button" \
"<p>Press <b>YesToAll</b> button to ignore other warnings automatically..." \
"<p>Or press <b>Abort</b> to cancel operation").arg(file1).arg(file2);
box.setModal(true);
box.setWindowTitle(name);
box.setText(QString::fromLatin1("%1").arg(text));
box.setIcon(QMessageBox::Question);
box.setStandardButtons(QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::Abort);
switch (box.exec()) {
case (QMessageBox::YesToAll):
warningFlag = false;
break;
case (QMessageBox::Yes):
break;
case (QMessageBox::Abort):
rmDirectoryRecursive(tmpFolder);
rmDirectoryRecursive(tmpFolderPlus);
setEnableGUI(true);
return;
}
}
}
}
And that's all. Good luck!

I wanted something similar, and was googling (in vain), so this is where I've got to:
static bool cpDir(const QString &srcPath, const QString &dstPath)
{
rmDir(dstPath);
QDir parentDstDir(QFileInfo(dstPath).path());
if (!parentDstDir.mkdir(QFileInfo(dstPath).fileName()))
return false;
QDir srcDir(srcPath);
foreach(const QFileInfo &info, srcDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
QString srcItemPath = srcPath + "/" + info.fileName();
QString dstItemPath = dstPath + "/" + info.fileName();
if (info.isDir()) {
if (!cpDir(srcItemPath, dstItemPath)) {
return false;
}
} else if (info.isFile()) {
if (!QFile::copy(srcItemPath, dstItemPath)) {
return false;
}
} else {
qDebug() << "Unhandled item" << info.filePath() << "in cpDir";
}
}
return true;
}
It uses an rmDir function that looks pretty similar:
static bool rmDir(const QString &dirPath)
{
QDir dir(dirPath);
if (!dir.exists())
return true;
foreach(const QFileInfo &info, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
if (info.isDir()) {
if (!rmDir(info.filePath()))
return false;
} else {
if (!dir.remove(info.fileName()))
return false;
}
}
QDir parentDir(QFileInfo(dirPath).path());
return parentDir.rmdir(QFileInfo(dirPath).fileName());
}
This doesn't handle links and special files, btw.

The hard way. Copy every file individually.
Use QDir::entryList() to iterate over the content of a directory
Use QDir::cd() and QDir::cdUp() to go in and out of directories
Use QDir::mkdir() and QDir::mkpath() to create the new folders tree
and finally, use QFile::copy() to copy the actual files

This is basically petch's answer with a slight change due to it breaking for me in Qt 5.6 (this is the top question hit), so all credit goes to petch.
function
bool copyPath(QString sourceDir, QString destinationDir, bool overWriteDirectory)
{
QDir originDirectory(sourceDir);
if (! originDirectory.exists())
{
return false;
}
QDir destinationDirectory(destinationDir);
if(destinationDirectory.exists() && !overWriteDirectory)
{
return false;
}
else if(destinationDirectory.exists() && overWriteDirectory)
{
destinationDirectory.removeRecursively();
}
originDirectory.mkpath(destinationDir);
foreach (QString directoryName, originDirectory.entryList(QDir::Dirs | \
QDir::NoDotAndDotDot))
{
QString destinationPath = destinationDir + "/" + directoryName;
originDirectory.mkpath(destinationPath);
copyPath(sourceDir + "/" + directoryName, destinationPath, overWriteDirectory);
}
foreach (QString fileName, originDirectory.entryList(QDir::Files))
{
QFile::copy(sourceDir + "/" + fileName, destinationDir + "/" + fileName);
}
/*! Possible race-condition mitigation? */
QDir finalDestination(destinationDir);
finalDestination.refresh();
if(finalDestination.exists())
{
return true;
}
return false;
}
Use:
/*! Overwrite existing directories. */
bool directoryCopied = copyPath(sourceDirectory, destinationDirectory, true);
/*! Do not overwrite existing directories. */
bool directoryCopied = copyPath(sourceDirectory, destinationDirectory, false);

Try this:
bool copyDirectoryFiles(const QString &fromDir, const QString &toDir, bool coverFileIfExist)
{
QDir sourceDir(fromDir);
QDir targetDir(toDir);
if(!targetDir.exists()){ /* if directory don't exists, build it */
if(!targetDir.mkdir(targetDir.absolutePath()))
return false;
}
QFileInfoList fileInfoList = sourceDir.entryInfoList();
foreach(QFileInfo fileInfo, fileInfoList){
if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
continue;
if(fileInfo.isDir()){ /* if it is directory, copy recursively*/
if(!copyDirectoryFiles(fileInfo.filePath(),
targetDir.filePath(fileInfo.fileName()),
coverFileIfExist))
return false;
}
else{ /* if coverFileIfExist == true, remove old file first */
if(coverFileIfExist && targetDir.exists(fileInfo.fileName())){
targetDir.remove(fileInfo.fileName());
}
// files copy
if(!QFile::copy(fileInfo.filePath(),
targetDir.filePath(fileInfo.fileName()))){
return false;
}
}
}
return true;
}

I have made a library to manipulate files by a shell command style API. It supports a recursively copy of files and handled several more conditions.
https://github.com/benlau/qtshell#cp
Example
cp("-a", ":/*", "/target"); // copy all files from qrc resource to target path recursively
cp("tmp.txt", "/tmp");
cp("*.txt", "/tmp");
cp("/tmp/123.txt", "456.txt");
cp("-va","src/*", "/tmp");
cp("-a", ":resource","/target");

Since I had some trouble with App-Bundles on macOS, here's a solution with QDirIterator
void copyAndReplaceFolderContents(const QString &fromDir, const QString &toDir, bool copyAndRemove = false) {
QDirIterator it(fromDir, QDirIterator::Subdirectories);
QDir dir(fromDir);
const int absSourcePathLength = dir.absoluteFilePath(fromDir).length();
while (it.hasNext()){
it.next();
const auto fileInfo = it.fileInfo();
if(!fileInfo.isHidden()) { //filters dot and dotdot
const QString subPathStructure = fileInfo.absoluteFilePath().mid(absSourcePathLength);
const QString constructedAbsolutePath = toDir + subPathStructure;
if(fileInfo.isDir()){
//Create directory in target folder
dir.mkpath(constructedAbsolutePath);
} else if(fileInfo.isFile()) {
//Copy File to target directory
//Remove file at target location, if it exists. Otherwise QFile::copy will fail
QFile::remove(constructedAbsolutePath);
QFile::copy(fileInfo.absoluteFilePath(), constructedAbsolutePath);
}
}
}
if(copyAndRemove)
dir.removeRecursively();
}

If you are on a linux based system and the cp command exists and can be run, then you can use a QProcess to launch a bash:
auto copy = new QProcess(this);
copy->start(QStringLiteral("cp -rv %1 %2").arg(sourceFolder, destinationFolder));
copy->waitForFinished();
copy->close();
cp details:
-r means recursively
-v means it prints the successfully copied file
Note: if the copy operation is long, then you need to managed the UI freezing, as noted here

Assuming the target location is empty "no existing files or folders
with the same names" and you have no problem to use a Recursive
function!! to copy a directory recursively then the code will be something like this
void copy_all(QString dst_loc, QString src_loc)
{
QDir src(src_loc);
for(QFileInfo file_info : src.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)){
if(file_info.isDir()){
src.mkpath(dst_loc+'/'+file_info.fileName());
copy_all(dst_loc+'/'+file_info.fileName(),file_info.absoluteFilePath());
}
QFile::copy(file_info.absoluteFilePath(), dst_loc+'/'+file_info.fileName());
}
}
if you ever dealt with tree data structures and tried to create a Recursive function to do a "depth-first search" Alogorithm you will get a 85% similar algorithm, which Actually I got this idea from.
The second way, is by using a map data structure to hold the current
fileInfoList in a directory, and the corresponding state to show if
you have used this fileInfo or not yet. and you gather all
information firstly about sub directories and files from the source location.
And this is how most OS and other file managers do to copy data, by showing you the size of files to be copied, how many files and folders are going to be copied, and finally, if there is any conflict of files or folders with the same name before you even initiate copying "if you will do the same algorithm with the destination so that you can match filenames".
Good luck!.

Related

How to implement clipboard actions for custom mime-types?

I am trying to implement copy/cut/paste in a complex application.
I have a QGraphicsScene that can contain QGraphicsItem subtypes of varied subtypes, fairly complex (with Item as a second parent storing custom properties).
I would copy/cut selected items, and paste them back in place.
I already have implemented it using a local version: a list of items.
void copyItemsActionOld()
{
foreach(QGraphicsItem* qItem, selectedItems())
{
Item* newItem = (dynamic_cast<Item*>(qItem))->createItemCopy();
m_itemClipboard.append(newItem);
}
}
On paste, I make a copy of all items in clipboard and add them to the scene. So simple.....
BUT
I need to implement it using the global system clipboard.
I saw that creating a custom mime type is as simple as calling setData on a QMimeData object, after I make up a format name... (I hope that is true)
static const QString _mimeType("application/myItem");
void copyItemsAction()
{
QMimeData* _mimeData = new QMimeData;
2 QByteArray _itemData = ?????;
_mimeData->setData(_mimeType, _itemData);
QClipboard* _clipboard = QApplication::clipboard();
_clipboard->clear();
_clipboard->setMimeData(_mimeData);
}
void pasteItemsAction()
{
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
QStringList _formats = _mimeData->formats();
foreach (QString _format, _formats)
{
if (_format == _mimeType)
{
QByteArray _itemData = _mimeData->data(_mimeType);
3 // then do what ? How do I parse it ?
}
}
}
My questions
1) Are the above fragments for copyItemsAction and pasteItemsAction anywhere close to how clipboard actions should work ?
2) How can I put item data in the QByteArray ?
3) How do I parse the data in QByteArray ?
4) Do I need to register the custom mime-type anywhere else ? (other than what I just did in my two functions); and will it be multi-platform ?
I have already implemented save and load functionality for all items. Something like...
void Item::saveItem(QDataStream &outFile)
{
outFile << type;
outFile << width;
outFile << color.name();
}
Can I use this to place the items data in the QByteArray ? (How ?)
I was on the right track, and I kept adding code to my question until I found how to make it work:
static const QString _mimeType("application/myItem");
void copyItemsAction()
{
QByteArray _itemData;
QDataStream outData(&_itemData, QIODevice::WriteOnly);
outData << selectedItems().size();
foreach(QGraphicsItem* qItem, selectedItems())
{
Item* item = dynamic_cast<Item*>(qItem);
item->saveItem(outData);
}
QMimeData* _mimeData = new QMimeData;
_mimeData->setData(_mimeType, _itemData);
_mimeData->setText("My Items");
QClipboard* _clipboard = QApplication::clipboard();
_clipboard->clear();
_clipboard->setMimeData(_mimeData);
}
void pasteItemsAction()
{
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
QStringList _formats = _mimeData->formats();
foreach (QString _format, _formats)
{
if (_format == _mimeType)
{
QByteArray _itemData = _mimeData->data(_mimeType);
QDataStream inData(&_itemData, QIODevice::ReadOnly);
int itemsSize;
inData >> itemsSize;
for (int i = 0; i < itemsSize; ++i)
{
Item* item = ...
item->loadItem(inData);
}
}
}
}
So, for question 1, yes I was on the right track;
For questions 2 and 3 - I was able to use a QDataStream to serialize info to/from the QByteArray.
If there is a better / more effective / faster way, I would love to know...
For question 4 - it seems that I can use just about any string, if all I want is to copy/paste within a single instance of my application.
It is also true if I want to use it between multiple applications, multiple instances of my application, or for drag-and-drop - on most platforms. (It does not seem to work between multiple applications/instances in the embedded platform I target.)
Caveat - it fails frequently when another clipboard using application is open, in windows.

How to use QFileDialog::getsaveFileName to save a ui file with QFormBuilder?

What I want:
When I call save(), I would like to use the QFileDialog to get the file, and save ui file with QFormBuilder(because it lets me save ui files recognizable by Qdesigner)
What I have:
I have a method called save()
void MainWindow::save()
{
QString savef = QFileDialog::getSaveFileName(this, tr("Save"), "file", tr("UI files (*.ui)"));
//here down I would like to use the savef to save ui file
QFormbuilder builder;
builder.save(savef, myui);
}
But savef is not QIODevice, and the Qt is complaining about it.
Any idea how I can do it?
Thanks.
You need to create a QFile and pass that to save():
QFile out(savef);
if (!out.open(QIODevice::WriteOnly)) {
const QString error = tr("Could not open %1 for writing: %2").arg(savef, out.errorString());
//report the error in some way...
return;
}
builder.save(&out, myui);
const bool flushed = out.flush();
if (!flushed || out.error() != QFile::NoError) { // QFormBuilder lacks proper error reporting...
const QString error = tr("Could not write form to %1: %2").arg(savef, out.errorString());
//report error
}
When using Qt 5.1 or newer, I'd use QSaveFile instead:
QSaveFile out(savef);
if (!out.open(QIODevice::WriteOnly)) {
const QString error = tr("Could not open %1 for writing: %2").arg(savef, out.errorString());
//report the error in some way...
return;
}
builder.save(&out, myui);
if (!out.commit()) {
//report error
}

how to determine if the mount successful in QT code

I have this function on mounting a smb:// connection. What if there is an error that is not in my condition. Is there a better way to determine if the mount is sucessful or not? Im using ubuntu 11.04 and qt 4.7.3
bool mwDM::mountFolder()
{
QString smbUsername,smbPassword,serverPath,mountPath;
QProcess connectSamba;
QString terminalCommand,linuxPassword;
QDir dir("/mnt/backup");
smbUsername=ReadINIStr(iniPath,"Server","Username","");
smbPassword=ReadINIStr(iniPath,"Server","Password","");
serverPath=ReadINIStr(iniPath,"Server","Hostname","");
serverPath="//" + serverPath;
mountPath="/mnt/backup";
linuxPassword=ReadINIStr(iniPath,"Server","AdminPassword","");
terminalCommand="echo "+linuxPassword+" | sudo -S mount -t cifs -o username="+smbUsername+",password="+smbPassword+" "+serverPath+ " "+mountPath;
connectSamba.start("sh",QStringList() << "-c" << terminalCommand );
if(!connectSamba.waitForStarted())
{
LogWrite("Failed to start mount command", Qt::red);
}
if(!connectSamba.waitForFinished() )
{
LogWrite("Failed to finish mount command", Qt::red);
}
QString connectSamba_stderr = connectSamba.readAllStandardError();
qDebug() << "connectSamba_stderr" << connectSamba_stderr;
if(connectSamba_stderr.contains("is not a valid block device"))
{
LogWrite("Hostname is invalid", Qt::red);
return false;
}
else if(connectSamba_stderr.contains("3 incorrect password attempts"))
{
LogWrite("Admin password is incorrect", Qt::red);
return false;
}
else if(connectSamba_stderr.contains("wrong fs type, bad option, bad superblock on"))
{
LogWrite("Hostname is invalid", Qt::red);
return false;
}
else if(connectSamba_stderr.contains("Invalid argument"))
{
LogWrite("Mount error(22): Invalid argument", Qt::red);
return false;
}
else if(!dir.exists())
{
LogWrite("Directory doesn't exists", Qt::red);
return false;
}
else
{
return true;
}
}
You can check last error of a QProcess by using error and state functions (Documentation for "error" Documentation for "state").
"What if there is an error that is not in my condition."
You can add something like this in your code:
else if(connectSamba.state() == QProcess::NotRunning && connectSamba.error() >= 0)
{
LogWrite("Unknown error", Qt::red);
return false;
}
Or, if you want to give more specific information, you can create a condition for each error code separately. Here's a list of codes.
Alternatively, don't add the above block to the error checking code. Instead, create a slot to which you connect the error signal of connectSamba class:
// add this line below "QProcess connectSamba;" line in mwDm::mountFolder
connect(&connectSamba, SIGNAL(error(QProcess::ProcessError)), this, SLOT(onError(QProcess::ProcessError));
// after that, use your original error checking code in mountFolder
// slot code
void mwDm::onError(QProcess::ProcessError)
{
//use switch-case or if to check type of error if you want
processErrorOccurred = true; // processErrorOccurred is a member of mwDm
}

QVector: no match for 'operator+'

I am passing a QVector from one window to another, I want to append the value present in QVector from previous window to a QString in present window. I get the error when I perform the addition no match for 'operator+'.
Here is my code:
Window1.cpp
void SelectOS::processNextButton()
{
if(ui->win32->isChecked()){
QString path;
path = qApp->applicationDirPath()+"/WIN/32Bit";
so->osName.push_back(path);
SelectSoftware *ss = new SelectSoftware();
this->hide();
ss->show();
}
}
QVector<QString> SelectOS::getosName(){
so = new SelectOS();
return so->osName;
}
Window2.cpp
void SelectSoftware::getSoftwareDetails()
{
SelectOS *so = new SelectOS();
SelectSoftware *ss = new SelectSoftware();
ss->os = so->getosName();
QString fileName = ss->os + "/" +SOFTWARELIST; // Here I get the error...
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString msg = "Could not find the file " + fileName;
errorExit(msg);
}
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
processLine(line.toLower());
}
}
Help me, thanks ...
Assuming SOFTWARELIST is a simple QString:
QString fileName = QString( "%1/%2" )
.arg( ss->os.last() )
.arg( SOFTWARELIST );
This means you are creating a QString with placeholders %1 and %2 where %1 will be replaced by the result of ss->os.last() which returns the last item in the vector and %2 will be replaced by whatever SOFTWARELIST is.
If SOFTWARELIST is a vector as well, you will need to call e.g. .last() on it as well.
QVector is a container class, which holds set of something. In your example set of QString's. So then you try to form a fileName which is a QString you obviously cannot add to a fileName QString list of other Qstring's. (truly saying you can, but not with '+' operator and slightly different code).
Honestly I didn't got straight away why you actually passing QVector if you only need an application path I would suggest to use just QString.

How to compress a few files to zip in Qt?

I need to zip a few files in Qt. I am trying Quazip. But the zip file contains files with 0kb size. Something goes wrong. Can somebody help me out here!
The code for zipping is given here:
QString testZip = location + "/tempTheme/test.zip";
QuaZip zip(testZip);
zip.setFileNameCodec("IBM866");
if(!zip.open(QuaZip::mdCreate)) {
qWarning("testCreate(): zip.open(): %d", zip.getZipError());
}
zip.setComment("Test comment");
QFileInfoList files=QDir(location + "/tempTheme/").entryInfoList();
QFile inFile;
QuaZipFile outFile(&zip);
char c;
foreach(QFileInfo file, files) {
if(!file.isFile()||file.fileName()=="test.zip") continue;
inFile.setFileName(file.fileName());
if(!inFile.open(QIODevice::ReadOnly)) {
qWarning("testCreate(): inFile.open(): %s", inFile.errorString().toLocal8Bit().constData());
}
if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(inFile.fileName(), inFile.fileName()))) {
qWarning("testCreate(): outFile.open(): %d", outFile.getZipError());
}
while(inFile.getChar(&c)&&outFile.putChar(c));
if(outFile.getZipError()!=UNZ_OK) {
qWarning("testCreate(): outFile.putChar(): %d", outFile.getZipError());
}
outFile.close();
if(outFile.getZipError()!=UNZ_OK) {
qWarning("testCreate(): outFile.close(): %d", outFile.getZipError());
}
inFile.close();
}
zip.close();
if(zip.getZipError()!=0) {
qWarning("testCreate(): zip.close(): %d", zip.getZipError());
QMessageBox msgInfo;
msgInfo.information(this, "blah", "done");
}
If this project is just a toy, character-at-a-time is probably fine, but I can't imagine adding one million characters one-at-a-time to a zip file manager would be very efficient. And a one megabyte file looks mighty small these days. So hunt around the QuaZip API for mechanisms to either add files directly to the zip, or at least large buffers of data at a time. (Qt's buffering saves system calls but one million function calls working on one character vs 128 function calls working with 8k buffers is going to be noticeable in most programs.)
I got the answer, I need to make changes as following,
QString testZip = location + "/test.zip";
QuaZip zip(testZip);
zip.setFileNameCodec("IBM866");
if(!zip.open(QuaZip::mdCreate)) {
qWarning("testCreate(): zip.open(): %d", zip.getZipError());
}
//zip.setComment("Test comment");
QFileInfoList files=QDir(location + "/tempTheme/").entryInfoList();
QFile inFile;
QFile inFileTmp;
QuaZipFile outFile(&zip);
char c;
foreach(QFileInfo file, files) {
if(!file.isFile()) continue;
inFileTmp.setFileName(file.fileName());
inFile.setFileName(file.filePath());
if(!inFile.open(QIODevice::ReadOnly)) {
qWarning("testCreate(): inFile.open(): %s", inFile.errorString().toLocal8Bit().constData());
}
if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(inFileTmp.fileName(), inFile.fileName()))) {
qWarning("testCreate(): outFile.open(): %d", outFile.getZipError());
}
while(inFile.getChar(&c)&&outFile.putChar(c));
if(outFile.getZipError()!=UNZ_OK) {
qWarning("testCreate(): outFile.putChar(): %d", outFile.getZipError());
}
outFile.close();
if(outFile.getZipError()!=UNZ_OK) {
qWarning("testCreate(): outFile.close(): %d", outFile.getZipError());
}
inFile.close();
}
zip.close();
if(zip.getZipError()!=0) {
qWarning("testCreate(): zip.close(): %d", zip.getZipError());
}
As mentioned earlier, if it is a toy app its okay to write char-to-char. But in real it is really wasting resources.
My solution is:
(QuaZipFile) zipout->write( (QFile)inFile->readAll() );
It reads the entire file with QFile than writes out with QuaZipFile.

Resources