中斷檔案複製與重新命名操作
在需要傳輸大檔案並且使用者需要能夠取消操作的情況下, Qt 提供的預設copy() 和rename() 方法可能會受到限制。挑戰在於如何在不引入顯著效能開銷或使用者挫折感的情況下中斷這些進程。
查詢 Qt 中的中斷支援
在研究 QFile 文件時,很明顯 Qt不提供用於中斷 copy() 或 rename() 操作的內建機制。因此,有必要考慮自訂實作策略來滿足此要求。
複製中斷的自訂實作
要建立非阻塞複製助手,一種選擇是實作專用執行緒或利用主執行緒。在任何一種情況下,都需要分段複製,即使用緩衝區以區塊的形式傳輸資料。透過使用緩衝區,可以追蹤操作進度並適應用戶取消請求。
實作自訂複製助理的核心步驟可以描述如下:
實作一個 step() 槽,利用 QMetaObject::invokeMethod() 和 Qt::QueuedConnection,它允許定期處理使用者事件。在此槽中:
範例實作
以下程式碼片段提供了複製助理類別的範例實作:
class CopyHelper : public QObject { Q_OBJECT Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged) public: CopyHelper(QString sPath, QString dPath, quint64 bSize = 1024 * 1024) : isCancelled(false), bufferSize(bSize), prog(0.0), source(sPath), destination(dPath), position(0) { } ~CopyHelper() { free(buff); } qreal progress() const { return prog; } void setProgress(qreal p) { if (p != prog) { prog = p; emit progressChanged(); } } public slots: void begin() { if (!source.open(QIODevice::ReadOnly)) { qDebug() << "could not open source, aborting"; emit done(); return; } fileSize = source.size(); if (!destination.open(QIODevice::WriteOnly)) { qDebug() << "could not open destination, aborting"; // maybe check for overwriting and ask to proceed emit done(); return; } if (!destination.resize(fileSize)) { qDebug() << "could not resize, aborting"; emit done(); return; } buff = (char*)malloc(bufferSize); if (!buff) { qDebug() << "could not allocate buffer, aborting"; emit done(); return; } QMetaObject::invokeMethod(this, "step", Qt::QueuedConnection); //timer.start(); } void step() { if (!isCancelled) { if (position < fileSize) { quint64 chunk = fileSize - position; quint64 l = chunk > bufferSize ? bufferSize : chunk; source.read(buff, l); destination.write(buff, l); position += l; source.seek(position); destination.seek(position); setProgress((qreal)position / fileSize); //std::this_thread::sleep_for(std::chrono::milliseconds(100)); // for testing QMetaObject::invokeMethod(this, "step", Qt::QueuedConnection); } else { //qDebug() << timer.elapsed(); emit done(); return; } } else { if (!destination.remove()) qDebug() << "delete failed"; emit done(); } } void cancel() { isCancelled = true; } signals: void progressChanged(); void done(); private: bool isCancelled; quint64 bufferSize; qreal prog; QFile source, destination; quint64 fileSize, position; char * buff; //QElapsedTimer timer; };
結論
透過實作自訂複製助理或使用提供的範例,可以建立可以被使用者中斷的非阻塞檔案複製操作。這種方法可以實現響應靈敏且用戶友好的文件傳輸,解決因無法取消的冗長操作而造成的挫敗感。
以上是如何中斷 Qt 中的檔案複製和重新命名操作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!