2017-08-08 104 views
0

這是一個關於在C++和Linux中使用QDataStream和QTemporaryFile的QT問題。QDataStream和Flush

我有一些問題得到一個QDataStream刷新。 QTextStream有一個flush函數,但QDataStream顯然不需要一個。 (2013年引用:http://www.qtcentre.org/threads/53042-QDataStream-and-flush())。我的問題是,這是真的/仍然是這種情況,並且無論如何強迫QDataStream刷新?

當我處理使用QDataStream寫入的文件時,最後一次寫入數量丟失(一次寫入5個字節時爲112個字節,每次寫入1個字節時爲22個字節)。但是,如果我在文件末尾寫入大量填充,則會出現所有內容(除填充的最後幾次寫入外)。這就是爲什麼我相信QDataStream沒有被刷新到文件。

我正在處理的文件是中等大小的原始二進制文件(大約2MB)。

這裏使用了一些我對處理文件的代碼的一個小例子:

void read_and_process_file(QString &filename) { 
    QFile inputFile(filename); 
    if (!inputFile.open(QIODevice::ReadOnly)) { 
    qDebug() << "Couldn't open: " << filename; 
    return; 
    } 
    QDataStream fstream(&inputFile); 
    QTemporaryFile *tempfile = new QTemporaryFile(); 
    if (!tempfile->open()) { 
    qDebug() << "Couldn't open tempfile"; 
    return; 
    } 
    QDataStream ostream(tempfile); 

    while (!fstream.atEnd()) { 
    int block_size = 5;  //The number to read at a time 
    char lines[block_size]; 

    //Read from the input file 
    int len = fstream.readRawData(lines,block_size); 
    QByteArray data(lines,len); 

    //Will process data here once copying works 

    //Write to the temporary file 
    ostream.writeRawData(data,data.size()); 
    } 
    process_file(tempfile); 
    delete tempfile; 
} 
+1

在調用'process_file(tempfile)'之前嘗試調用'tempfile-> close()'。 – hank

+0

漢克,這似乎消除了這個問題,謝謝。如果臨時文件被關閉,是不是有可能清理掉它?我將運行一些測試並檢查它。 –

+1

不,'QTemporaryFile :: close'不會刪除文件。當QTemporaryFile對象被銷燬時,該文件被刪除。此外,我會建議不要使用'new'在單個作用域內分配對象,因爲這可能會導致內存泄漏。在你的例子中,你會在'無法打開臨時文件'後發生泄漏。只需在堆棧上分配你的對象:'QTemporaryFile tempfile;' – hank

回答

2

這個答案的第一部分是獨立的沖洗到磁盤文件的問題。


使用!fstream.atEnd()作爲條件的while是不是一個好主意。見http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong。我想改變while環路:

const int block_size = 5;  //The number to read at a time 
char lines[block_size]; 
int len = 0; 
while ((len = fstream.readRawData(lines,block_size)) > 0) { 

    QByteArray data(lines, len); 

    //Will process data here once copying works 

    //Write to the temporary file 
    ostream.writeRawData(data,data.size()); 
} 

不過,我看不出使用中間QByteArray點。該循環可以簡化爲:如果您需要處理QByteArray其他的東西

while ((len = fstream.readRawData(lines,block_size)) > 0) { 
    //Write to the temporary file 
    ostream.writeRawData(lines, len); 
} 

,它的罰款,以構建一個使用它,但調用ostream.writeRawData並不需要使用它。


Re。該文件的問題沒有得到刷新,我會建議使用嵌套的範圍來打開文件。該文件應該在範圍的末尾被刷新並關閉。

void read_and_process_file(QString &filename) { 

    QFile inputFile(filename); 
    if (!inputFile.open(QIODevice::ReadOnly)) { 
     qDebug() << "Couldn't open: " << filename; 
     return; 
    } 

    QDataStream fstream(&inputFile); 
    QTemporaryFile *tempfile = new QTemporaryFile(); 
    if (!tempfile->open()) { 
     qDebug() << "Couldn't open tempfile"; 
     return; 
    } 

    // Create a nested scope for the QDataStream 
    // object so it gets flushed and closed when the 
    // scope ends. 
    { 
     QDataStream ostream(tempfile); 

     const int block_size = 5;  //The number to read at a time 
     char lines[block_size]; 
     int len = 0; 
     while ((len = fstream.readRawData(lines,block_size)) > 0) { 

     QByteArray data(lines, len); 

     //Will process data here once copying works 

     //Write to the temporary file 
     ostream.writeRawData(lines, len); 
     } 

     // The QDataStream should be flushed and 
     // closed at the end of this scope. 
    } 

    process_file(tempfile); 
    delete tempfile; 
} 
+0

謝謝,很好的建議。我改變了循環,只有當你的原始評論建議len <= 0時才結束。你是對的,QByteArray不是一個簡單的例子。不幸的是,雖然這很有用,但它不能解決問題。 –

+0

@Weir_Doe,查看更新。 –