Имам UI приложение в C++ и QT5.4, използвам CryptoPP 5.6.2 за криптиране на файлове. Попаднах на следния проблем:
Когато се натисне бутонът Encrypt, се стартира нова нишка въз основа на този урок.
// 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();
Съхранявам указател към нишката и работника в класа mainwindow (родител на бутона за шифроване и по този начин слота)
Работническа класа:
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()
и да увеличавам броячите на данни ).
В този момент съм заседнал и не мога да намеря решение. Моля помогнете.