#include #include #include #include "filecopier.h" FileCopier::FileCopier(QObject *parent) : QThread(parent), mCancel(false), mTotal(0), mCopied(0){} void FileCopier::addJob(const QString &source, const QString &dest){ QMutexLocker l(&mAddJobMutex); if(!mJobs.contains(source)){ mJobs[source] = dest; ++mTotal; } } void FileCopier::run(){ int bufsize = 32 * 1024 * 1024; char *buf = new char[bufsize]; mCancel = false; mCopied = 0; QElapsedTimer et; while(!mJobs.isEmpty()){ mAddJobMutex.lock(); auto first = mJobs.constBegin(); auto source = first.key(); auto dest = first.value(); mJobs.remove(source); mAddJobMutex.unlock(); QFile sFile(source); QFile dFile(dest); bool openSource = sFile.open(QIODevice::ReadOnly); bool openDest = dFile.open(QIODevice::WriteOnly); if(!openSource || !openDest){ emit success(false, source); goto cleanup; } emit newFile(source, dest, sFile.size()); int read = 0; qint64 total = 0; qint64 elapsed = 0; qint64 bytesSinceEl = 0; et.start(); while(!sFile.atEnd()){ read = sFile.read(buf, bufsize); dFile.write(buf, read); total += read; bytesSinceEl += read; elapsed = et.elapsed(); if(elapsed > 1000){ mCancelMutex.lock(); bool cancel = mCancel; mCancelMutex.unlock(); if(cancel){ dFile.close(); QFile::remove(dest); emit success(false, source); goto cleanup; } mCountMutex.lock(); emit bytesReadIntval(bytesSinceEl, elapsed, mTotal, mCopied); mCountMutex.unlock(); elapsed = 0; bytesSinceEl = 0; et.restart(); } emit bytesRead(total); } emit success(true, source); ++mCopied; emit bytesReadIntval(bytesSinceEl, elapsed, mTotal, mCopied); et.restart(); } cleanup: delete buf; mTotal = 0; mJobs.clear(); } void FileCopier::cancel(){ QMutexLocker l(&mCancelMutex); mCancel = true; }