无法在线程 运行 方法中使用 CryptoPP FileSink 运行ning 终止 Qt 线程

Cannot kill Qt thread with CryptoPP FileSink running in the thread run method

我在 C++ 和 QT5.4 中有一个 UI 应用程序,我使用 CryptoPP 5.6.2 来加密文件。我运行遇到以下问题:

  1. 当点击加密按钮时,一个新的线程被启动基于this tutorial

    // new thread
    CryptoWorkerThread = new QThread;
    this->worker = new CryptoWorker(fileName.c_str(), newFileName.c_str(), key, keyLength, iv);
    this->worker->moveToThread(CryptoWorkerThread);
    connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
    connect(CryptoWorkerThread, SIGNAL(started()), worker, SLOT(process()));
    connect(worker, SIGNAL(finished()), CryptoWorkerThread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), this, SLOT(on_CryptoWorker_finished()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(CryptoWorkerThread, SIGNAL(finished()), CryptoWorkerThread, SLOT(deleteLater()));
    CryptoWorkerThread->start();
    
  2. 我在主窗口中存储指向线程和工作线程的指针class(加密按钮的父级,因此是插槽)

    工人Class:

    class CryptoWorker : public QObject {
        Q_OBJECT
    public:
        CryptoWorker(const char* sourceFileName, const char* destFileName, const byte * key, int keyLength, const byte * iv);
        ~CryptoWorker();
    
        const char* sourceFileName;
        const char* destFileName;
    
        public slots:
        void process();
    
    signals:
        void finished();
        void error(QString err);
    
    private:
        // add your variables here
        const byte* key;
        const byte* iv;
        int keyLength;
    };
    
    CryptoWorker::CryptoWorker(const char* sourceFileName, const char* destFileName, const byte * key, int keyLength, const byte * iv){
        this->sourceFileName = sourceFileName;
        this->destFileName = destFileName;
        this->key = key;
        this->keyLength = keyLength;
        this->iv = iv;
    }
    
    CryptoWorker::~CryptoWorker(){
    
    }
    
    void CryptoWorker::process(){
    
        CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryptor(key, keyLength, iv);
    
    
        CryptoPP::FileSource(sourceFileName, true,
            new CryptoPP::StreamTransformationFilter(
                encryptor,
                new CryptoPP::FileSink(destFileName),
                CryptoPP::BlockPaddingSchemeDef::PKCS_PADDING
            ),
            true // StreamTransformationFilter
        ); // FileSource
    
        emit finished();
    
        return;
    }
    

现在,当线程 运行 并且我正在使用此函数将文件 A 动态加密到文件 B 时:

CryptoPP::FileSource(sourceFileName, true,
        new CryptoPP::StreamTransformationFilter(
            encryptor,
            new CryptoPP::FileSink(destFileName),
            CryptoPP::BlockPaddingSchemeDef::PKCS_PADDING
        ),
        true // StreamTransformationFilter
); // FileSource

但是,线程会卡住,直到文件完成编码和写入,这可能需要几分钟。我没有办法终止线程,因为没有地方放置 isAlive() 检查。

我正在尝试找到一个解决方案,允许我使用 FileSource、FileSink(与 fstream 或 file 或 qfile 相比,速度非常惊人)并且还允许我在某个时候取消操作。

我通过添加另一个线程来检查正在创建的新加密文件 B 的大小来解决进度监控,但是控制在给定时刻正在写入的字节会很酷(这样我就可以检查isAlive() 并递增数据计数器)。

至此我卡住了,找不到解决办法。请帮忙。

您可以尝试将 false 传递给 FileSource 构造函数的第二个参数 (pumpAll),并使用 Pump 方法在循环中分块执行工作 - 这应该允许检查 isAlive 并增加计数器。