> 백엔드 개발 > C++ > 본문

Qt에서 파일 복사 및 이름 바꾸기 작업을 어떻게 중단할 수 있습니까?

Susan Sarandon
풀어 주다: 2024-11-13 15:33:02
원래의
993명이 탐색했습니다.

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

파일 복사 및 이름 바꾸기 작업 중단

대용량 파일을 전송해야 하고 사용자가 작업을 취소할 수 있어야 하는 상황에서는 Qt가 제공하는 기본 copy() 및 rename() 메소드는 제한될 수 있습니다. 문제는 상당한 성능 오버헤드나 사용자 좌절을 초래하지 않고 이러한 프로세스를 중단하는 것입니다.

Qt에서 중단 지원 쿼리

QFile 문서를 조사하는 동안 Qt가 copy() 또는 rename() 작업을 중단하기 위한 내장 메커니즘을 제공하지 않습니다. 따라서 이 요구 사항을 해결하려면 사용자 정의 구현 전략을 고려해야 합니다.

복사 인터럽트에 대한 사용자 정의 구현

비차단 복사 도우미를 만들려면 다음 옵션 중 하나를 사용하세요. 전용 스레드를 구현하거나 메인 스레드를 활용합니다. 두 시나리오 모두에서 데이터가 버퍼를 사용하여 청크로 전송되는 조각화된 복사가 필요합니다. 버퍼를 사용하면 작업 진행 상황을 추적하고 사용자 취소 요청을 수용할 수 있습니다.

사용자 지정 복사 도우미를 구현하는 핵심 단계는 다음과 같습니다.

  1. 복사 작업을 처리하기 위해 QObject 파생 클래스를 만듭니다.
  2. 소스 경로, 대상 경로, 버퍼 크기, 진행률 및 정리에 대한 속성을 초기화합니다. 취소.
  3. begin() 슬롯을 정의하여 소스 및 대상 파일 열기 및 데이터 전송을 위한 버퍼 할당을 포함하는 복사 프로세스를 시작합니다.
  4. step() 슬롯 구현 , Qt::QueuedConnection과 함께 QMetaObject::invokeMethod()를 활용하여 사용자 이벤트를 주기적으로 처리할 수 있습니다. 이 슬롯 내에서:

    • 복사가 취소되지 않았는지 확인하세요.
    • 소스 및 대상 파일을 사용하여 데이터를 청크로 읽고 씁니다.
    • 위치 대 파일 크기의 비율.
    • 전체 파일이 복사되거나 복사될 때까지 step() 슬롯을 반복적으로 호출합니다. 취소되었습니다.
  5. 사용자가 복사 작업을 중단하고 필요한 경우 대상 파일을 제거할 수 있도록 취소() 슬롯을 정의합니다.
  6. 신호를 활용하여 이해관계자에게 진행 상황을 알립니다. 변경 및 완료(done()).

예 구현

다음 코드 조각은 복사 도우미 클래스의 구현 예를 제공합니다.

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿