標籤:
檔案操作是應用程式必不可少的部分。Qt 作為一個通用開發庫,提供了跨平台的檔案操作能力。從本章開始,我們來瞭解下 Qt 的檔案以及輸入輸出的功能,也就是 I/O 系統。
Qt 通過QIODevice提供了對 I/O 裝置的抽象,這些裝置具有讀寫位元組塊的能力。下面是 I/O 裝置的類圖:
Qt4
Qt5
從上面的類圖可以看出,Qt4 和 Qt5 在 I/O 裝置部分大同小異。只不過 Qt5 新增加了一個QFileDevice類。途中所涉及的類及其用途簡要說明如下:
QIODevice:所有 I/O 裝置類的父類,提供了位元組塊讀寫的通用操作以及基本介面;
QFlie:訪問本地檔案或者嵌入資源;
QTemporaryFile:建立和訪問本地檔案系統的臨時檔案;
QBuffer:讀寫QByteArray;
QProcess:運行外部程式,處理進程間通訊;
QAbstractSocket:所有通訊端類的父類;
QTcpSocket:TCP協議網路資料轉送;
QUdpSocket:傳輸 UDP 報文;
QSslSocket:使用 SSL/TLS 傳輸資料;
QFileDevice:Qt5新增加的類,提供了有關檔案操作的通用實現。
這其中,QProcess、QTcpSocket、QUdpSoctet和QSslSocket是順序訪問裝置。所謂“順序訪問”,是指它們的資料只能訪問一遍:從頭走到尾,從第一個位元組開始訪問,直到最後一個位元組,中途不能返回去讀取上一個位元組;QFile、QTemporaryFile和QBuffer是隨機訪問裝置,可以訪問任意位置任意次數,還可以使用QIODevice::seek()函數來重新置放檔案訪問位置指標。
本章將主要介紹QFile及其相關類,後面的章節則開始介紹有關輸入輸出的流。
在所有的 I/O 裝置中,檔案 I/O 是最重要的部分之一。因為我們大多數的程式依舊需要首先訪問本地檔案(當然,在雲端運算大行其道的將來,這一觀點可能改變)。QFile提供了從檔案中讀取和寫入資料的能力。Qt5 新加入的QFileDevice類,則將這部分公用操作放到了這個單獨的類中。顯然,這部分代碼在 Qt4 中位於QFile類。這樣看來,Qt5 的代碼結構更為清晰,層次更好。
我們通常會將檔案路徑作為參數傳給QFile的建構函式。不過也可以在建立好對象最後,使用setFileName()來修改。QFile需要使用 / 作為檔案分隔字元,不過,它會自動將其轉換成作業系統所需要的形式。例如 C:/windows 這樣的路徑在 Windows 平台下同樣是可以的。
QFile主要提供了有關檔案的各種操作,比如開啟檔案、關閉檔案、重新整理檔案等。我們可以使用QDataStream或QTextStream類來讀寫檔案,也可以使用QIODevice類提供的read()、readLine()、readAll()以及write()這樣的函數。值得注意的是,有關檔案本身的資訊,比如檔案名稱、檔案所在目錄的名字等,則是通過QFileInfo擷取,而不是自己分析檔案路徑字串。
下面我們使用一段代碼來看看QFile的有關操作:
| 123456789101112131415161718192021222324 |
int main(int argc, char *argv[]){ QApplication app(argc, argv); QFile file("in.txt"); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Open file failed."; return -1; } else { while (!file.atEnd()) { qDebug() << file.readLine(); } } QFileInfo info(file); qDebug() << info.isDir(); qDebug() << info.isExecutable(); qDebug() << info.baseName(); qDebug() << info.completeBaseName(); qDebug() << info.suffix(); qDebug() << info.completeSuffix(); return app.exec();} |
在這段代碼中,我們首先使用QFile建立了一個檔案對象。這個檔案名稱字是 in.txt。如果你不知道應該把它放在哪裡,可以使用app.applicationFilePath();或者app.applicationDirPath();來獲得應用程式的執行路徑。只要將這個檔案放在同執行路徑一致的目錄下即可。可以使用QDir::currentPath()來獲得應用程式執行時的當前路徑。只要將這個檔案放在與當前路徑一致的目錄下即可。然後,我們使用open()函數開啟這個檔案,開啟形式是唯讀方式,文字格式設定。這個類似於fopen()的 r 這樣的參數。open()函數返回一個 bool 類型,如果開啟失敗,我們在控制台輸出一段提示然後程式退出。否則,我們利用 while 迴圈,將每一行讀到的內容輸出。
程式的第二部分,我們使用QFileInfo擷取有關該檔案的資訊。QFileInfo有很多類型的函數,我們只舉出一些例子。比如這裡,isDir()檢查該檔案是否是目錄;isExecutable()檢查該檔案是否是可執行檔等。baseName()可以直接獲得檔案名稱;suffix()則直接擷取檔案尾碼名。我們可以由下面的樣本看到,baseName()和completeBaseName(),以及suffix()和completeSuffix()的區別:
| 12345 |
QFileInfo fi("/tmp/archive.tar.gz");QString base = fi.baseName(); // base = "archive"QString cbase = fi.completeBaseName(); // base = "archive.tar"QString ext = fi.suffix(); // ext = "gz"QString ext = fi.completeSuffix(); // ext = "tar.gz" |
Qt 學習之路 :檔案