使用QSaveFile類安全的讀寫文件

QSaveFile類也是一種I/O設備,來用來讀寫文本文件和二進制文件,但使用該類的話,在寫入操作失敗時不會導致已經存在的數據丟失。

該類在執行寫操作時,會先將內容寫入到一個臨時文件中,如果沒有錯誤發生,我們可以在最後調用其成員函數commit()來將臨時文件中的內容移到目標文件中。這能確保目標文件中的數據在寫操作發生錯誤時不會丟失數據,也不會出現部分寫入的情況。所以,一般使用QSaveFile類向磁盤上保存整份文檔。

QSaveFile會自動的檢測寫入過程中所出現的錯誤,例如無法寫入全部的數據。它會記得有錯誤發生,並在commit()時放棄臨時文件。

至於該類的使用,和QFile類似,使用open()函數打開文件,使用QDataStream或QTextStream類進行讀寫,也可以使用從QIODevice繼承的函數read(),readLine(),write()等。但不同的是,不能調用close()函數,而應該調用commit()函數。如果沒有調用commit()函數,則QSaveFile對象銷燬時,會丟棄臨時文件。

當然,當應用程序出錯時,我們也可以主動放棄寫入的數據,只要調用cancelWriting()即可,這樣,即使以後又調用了commit(),也不會發生真正的保存文件操作。

使用該類,我們也可以跳過臨時文件,直接將數據寫入到目標文件中。上面我們說過,QSaveFile類會在和目標文件的同一目錄下創建一個臨時文件,並自動的進行重命名。但如果該目錄的權限限制不允許創建文件呢。通常,在這種情況下,open()調用會失敗。而爲了解決這個問題,即能讓用戶編輯一個現存的文件,而不創建新文件,可以調用setDirectWriteFallback(),爲其傳入true,這樣,在接下來調用open()時就會退回到直接打開目標文件,並向其寫入數據,而不會使用一個臨時文件。但這也會失去QSaveFile提供的原子保證功能,即在寫入出錯的情況下,可能會導致部分寫入的情況,並且會使cancelWriting()函數失效。

下面,我們使用一個例子來使用以下該類。

新建一個Qt控制檯程序,代碼如下:

#include <QCoreApplication>
#include <QSaveFile>
#include <QFile>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile file("test.txt");
    //QSaveFile file("test.txt");
    if(!file.open(QIODevice::WriteOnly))
    {
        return 0;
    }
    int i = 1;
    while(1)
    {
        QString str = QString("hello %1\n").arg(i++);
        file.write(str.toLocal8Bit());
        qDebug() << str;
    }

    return a.exec();
}

我們使用一個死循環往一個文件中寫數據,如果我們在循環的過程中,直接退出程序,對於這種情況,如果我們使用的是QFile類,那麼將會在磁盤上產生一個test.txt文件,裏面存儲的是程序退出前所寫入的內容。如下:



而如果我們使用QSaveFile,那麼將不會在磁盤上生成目標文件test.txt,而是會將這些數據存儲到所生成的一個臨時文件中:如下:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章