2014-03-31 48 views
4

我有一個主線程和一個處理某些文件的線程。當主線程監視的文件夾發生更改時,會向處理線程發送信號以啓動。處理完一個文件後,我想將其刪除,然後讓文件夾檢查文件夾中是否還有其他文件。如果有,然後重複該過程。通過更改內容從文件夾中刪除文件

我的問題是在文件夾的重複檢查。在處理線程上。該功能在下面的代碼中列出,問題是我無法從文件夾中刪除文件。我相當卡住,所以任何輸入讚賞。

在dataprocessor.h

... 
QList<QString> justProcessed; 
... 

在dataprocessor.cpp

void DataProcessor::onSignal() { 
// Will keep running as long as there are files in the spool folder, eating it's way through 
bool stillFiles = true; 

QDir dir(this->monitoredPath); 
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot); 
dir.setSorting(QDir::Time); 

while(stillFiles) { 

    // Have to update on each iteration, since the folder changes. 
    dir.refresh(); 

    QFileInfoList fileList = dir.entryInfoList(); 
    QString activeFile = ""; 

    foreach(QFileInfo file, fileList) { 

     if((file.suffix() == "txt") && !justProcessed.contains(file.fileName())) { 
      // Is a text file. Set for processing and break foreach loop 
      activeFile = file.fileName(); 
      break; 
     } 

    } 

    // If none of the files passed the requirements, then there are no more spl files in the folder. 
    qDebug() << activeFile; 
    if(activeFile == "") { 
     qDebug() << "Finished"; 
     emit finished(); 
     stillFiles = false; 
    } 

    // File is a new file, start processing 
    qDebug() << "Selected for processing"; 
    qDebug() << monitoredPath + "/" + activeFile; 
    if(!dir.remove(monitoredPath + "/" + activeFile)) qDebug() << "Could not remove file"; 

    justProcessed.append(activeFile); 

} // While end 
} 

請讓我知道如果我錯過了提供一些信息。

+0

您的後臺打印程序服務是否正在運行? – Nejat

+0

「我無法從文件夾中刪除文件」 - 這是什麼意思? remove()是否返回false?然後使用'activeFile = file.absoluteFilePath();'來獲得完整的路徑,這更容易處理。然後,刪除它:'QFile f(activeFile); if(!f.remove())qDebug(「Could not remove%s:%s」,qPrintable(activeFile),qPrintable(f.errorString()));'要了解爲什麼失敗。 –

+0

@KubaOber我初始化QString的原因是因爲我在線程中初始化時遇到了其他問題。如果我例如定義一個int並且我沒有用例如一個0,然後我得到什麼看起來是一個內存地址,即使我沒有初始化它作爲一個指針。我有一天學會了如何使用線程,所以有些事情我還不確定。用'isEmpty()'表示好點。謝謝。 – Attaque

回答

0

問題原來是兩個問題。其中一個問題是系統速度太快,因此在系統同時讀取和刪除文件。我通過添加一個QTimer解決了這個問題,每當來自監控文件夾的信號被觸發時,QTimer就被重置。距離系統的最後一次更改僅500毫秒就足夠了。而不是繼續使用QFileSystemWatcher讀取該文件夾中的文件並將它們添加到隊列中,正如我原來所做的那樣,我創建了一個函數來在處理文件夾中的文件時將系統監視器靜音。爲了補償文件監視器的功能,我在處理線程中創建了一個遞歸循環,以便只要文件仍然存在,它就會繼續讀取指定的文件。這可以在一個線程中完成。你們都聊代碼,所以這裏有雲:

信號和插槽設置

// Setting up folder monitoring. 
watcher.addPath(worker->monitoredPath); 
QObject::connect(&watcher, SIGNAL(directoryChanged(QString)), this, 
SLOT(updateQueue())); 
// Timer 
connect(timer, SIGNAL(timeout()), this, SLOT(startProcess())); 
connect(this, SIGNAL(processRequest()), thread, SLOT(start())); 
... 

void MainWindow::updateQueue() { 
    // Starts or restarts the call to start process. Prevents multiple signals from 
    // many files added at once 
    timer->start(500); 
} 
... 
void MainWindow::startProcess() { 

    if(!thread->isRunning()) { 
    emit processRequest(); 
    muteWatcher(true); // From here on a recursive loop in dataprocessor checks 
         // the folder for new files. 
    } 
    timer->stop(); 

} 

靜音文件守望

void MainWindow::muteWatcher(bool toggle) { 
    if(toggle) { 
    watcher.removePath(worker->monitoredPath); 
    } else { 
    watcher.addPath(worker->monitoredPath); 
    } 
} 

處理線程

void DataProcessor::initialize() { 
    QDir dir(this->monitoredPath); 
    dir.setFilter(QDir::NoDotAndDotDot | QDir::Files); 
    dir.setSorting(QDir::Time); 

    QList<QString> dFiles; 

    foreach(QFileInfo file, dir.entryInfoList()) { 

    if(file.suffix().toLower() == "txt") { 
     dFiles.append(file.fileName()); 
    } 
    } 

    if(dFiles.count() == 0) { // Base case 
    emit muteWatcher(false); // Start monitoring the folder again 
    emit finished(); // end the thread 
    return true; 
    } 

    // PROCESSING HERE 

    initializeLabel(); 

} 

接下來就是轉到我打印的打印機的首選項,以防止此打印機將spool文件添加到該文件夾​​中。您可以通過點擊「直接打印到打印機」來啓用此功能。這解決了我的大部分問題,並且我能夠刪除我創建的一個延遲網絡,以便使程序不會讀取打印機生成的文件。

希望這可以幫助別人!

相關問題