Maison > développement back-end > C++ > Comment puis-je interrompre les opérations de copie et de renommage de fichiers dans Qt ?

Comment puis-je interrompre les opérations de copie et de renommage de fichiers dans Qt ?

Susan Sarandon
Libérer: 2024-11-13 15:33:02
original
999 Les gens l'ont consulté

How can I interrupt file copy and rename operations in Qt?

Interruption des opérations de copie et de renommage de fichiers

Dans les situations où des fichiers volumineux doivent être transférés et où les utilisateurs ont besoin de pouvoir annuler l'opération, le Les méthodes par défaut copy() et rename() proposées par Qt peuvent être limitantes. Le défi réside dans l'interruption de ces processus sans introduire de surcharge de performances significative ni de frustration des utilisateurs.

Interrogation de la prise en charge des interruptions dans Qt

En examinant la documentation de QFile, il devient évident que Qt ne fournit pas de mécanisme intégré pour interrompre les opérations copy() ou rename(). Par conséquent, il est nécessaire d'envisager des stratégies de mise en œuvre personnalisées pour répondre à cette exigence.

Implémentation personnalisée pour l'interruption de copie

Pour créer un assistant de copie non bloquant, une option est pour implémenter un thread dédié ou utiliser le thread principal. Dans les deux cas, une copie fragmentée est nécessaire, où les données sont transférées par morceaux à l'aide d'un tampon. En utilisant un tampon, il est possible de suivre la progression de l'opération et de répondre aux demandes d'annulation des utilisateurs.

Les étapes principales de la mise en œuvre d'un assistant de copie personnalisé peuvent être décrites comme suit :

  1. Créez une classe dérivée de QObject pour gérer l'opération de copie.
  2. Initialisez les propriétés du chemin source, du chemin de destination, de la taille du tampon, de la progression et du nettoyage en cas d'annulation.
  3. Définissez un début ( ) pour lancer le processus de copie, qui comprend l'ouverture des fichiers source et de destination et l'allocation d'un tampon pour le transfert de données.
  4. Implémentez un slot step(), en utilisant QMetaObject::invokeMethod() avec Qt:: QueuedConnection, qui permet le traitement périodique des événements utilisateur. Dans cet emplacement :

    • Vérifiez si la copie n'est pas annulée.
    • Lisez et écrivez les données en morceaux à l'aide des fichiers source et de destination.
    • Mettez à jour la progression en fonction de la rapport entre la position et la taille du fichier.
    • Invoquez de manière récursive l'emplacement step() jusqu'à ce que l'intégralité du fichier soit copié ou annulé.
  5. Définissez un emplacement Cancel() pour permettre aux utilisateurs pour interrompre l'opération de copie et supprimer le fichier de destination si nécessaire.
  6. Utiliser des signaux pour informer les parties intéressées de la progression des modifications et de l'achèvement (done()).

Exemple de mise en œuvre

L'extrait de code suivant fournit un exemple d'implémentation d'une classe d'assistance à la copie :

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;
};
Copier après la connexion

Conclusion

En implémentant une copie personnalisée helper ou en utilisant l'exemple fourni, il est possible de créer une opération de copie de fichier non bloquante qui peut être interrompue par les utilisateurs. Cette approche permet des transferts de fichiers réactifs et conviviaux, résolvant les frustrations causées par des opérations longues qui ne peuvent pas être annulées.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal