Qt QFile文件操作的具體使用
很多應用程序都需要具備操作文件的能力,包括對文件內容進行讀/寫、創建和刪除文件等,甚至某些應用程序的誕生純粹是為瞭操作文件,比如 WPS Office、PDFedit 等。為此,Qt 框架提供瞭 QFile 類專門用來操作文件。
QFile文件操作
QFile 類支持對文件進行讀取、寫入、刪除、重命名、拷貝等操作,它既可以操作文件文件,也可以操作二進制文件。
使用 QFile 類操作文件之前,程序中需引入<QFile>頭文件。創建 QFile 類的對象,常用的構造函數有:
QFile::QFile() QFile::QFile(const QString &name)
參數 name 用來指定要操作的目標文件,包含文件的存儲路徑和文件名,存儲路徑可以使用絕對路徑(比如 “D:/Demo/test.txt”)或者相對路徑(比如”./Demo/test.txt”),路徑中的分隔符要用 “/” 表示。
通常情況下,我們會調用第二個構造函數,直接指明要操作的文件。對於第一個構造函數創建的 QFile 對象,需要再調用 setFileName() 方法指明要操作的文件。
與 C++ 讀寫文件的規則一樣,使用 QFile 讀寫文件之前必須先打開文件,調用 open() 成員方法即可,常用的語法格式為:
bool QFile::open(OpenMode mode)
mode 參數用來指定文件的打開方式,下表羅列瞭此參數的可選值以及各自的含義:
打開方式 | 含 義 |
---|---|
QIODevice::ReadOnly | 隻能對文件進行讀操作 |
QIODevice::WriteOnly | 隻能對文件進行寫操作,如果目標文件不存在,會自行創建一個新文件。 |
QIODevice::ReadWrite | 等價於 ReadOnly | WriteOnly,能對文件進行讀和寫操作。 |
QIODevice::Append | 以追加模式打開文件,寫入的數據會追加到文件的末尾(文件原有的內容保留)。 |
QIODevice::Truncate | 以重寫模式打開,寫入的數據會將原有數據全部清除。註意,此打開方式不能單獨使用,通常會和 ReadOnly 或 WriteOnly 搭配。 |
QIODevice::Text | 讀取文件時,會將行尾結束符(Unix 系統中是 “\n”,Windows 系統中是 “\r\n”)轉換成‘\n’;將數據寫入文件時,會將行尾結束符轉換成本地格式,例如 Win32 平臺上是‘\r\n’。 |
表 1 QFile文件打開方式
根據需要,可以為 mode 參數一次性指定多個值,值和值之間用|分割。比如:
- QIODevice::ReadOnly | QIODevice::Text:表示隻允許對文件進行讀操作,讀取文件時,會將行尾結束符轉換為 ‘\n’;
- QIODevice::WriteOnly | QIODevice::Text:表示隻允許對文件進行寫操作,將數據寫入文件時,會將行尾結束符轉換為本地格式;
- QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text:表示對文件進行寫操作,寫入的數據會存放到文件的尾部,同時數據中的行尾結束符轉換為本地格式。
註意,傳遞給 mode 參數的多個值之間不能相互沖突,比如 Append 和 Truncate 不能同時使用。
如果文件成功打開,open() 函數返回 true,否則返回 false。
QFile 類提供瞭很多功能實用的方法,可以快速完成對文件的操作,下表列舉瞭常用的一些:
普通成員方法 | 功 能 |
---|---|
qint64 QFile::size() const | 獲取當前文件的大小。對於打開的文件,該方法返回文件中可以讀取的字節數。 |
bool QIODevice::getChar(char *c) | 從文件中讀取一個字符,並存儲到 c 中。讀取成功時,方法返回 true,否則返回 false。 |
bool QIODevice::putChar(char c) | 向文件中寫入字符 c,成功時返回 true,否則返回 false。 |
QByteArray QIODevice::read(qint64 maxSize) | 從文件中一次性最多讀取 maxSize 個字節,然後返回讀取到的字節。 |
qint64 QIODevice::read(char *data, qint64 maxSize) | 從文件中一次性對多讀取 maxSize 個字節,讀取到的字節存儲到 data 指針指定的內存控件中。該方法返回成功讀取到的字節數。 |
QByteArray QIODevice::readAll() | 讀取文件中所有的數據。 |
qint64 QIODevice::readLine(char *data, qint64 maxSize) | 每次從文件中讀取一行數據或者讀取最多 maxSize-1 個字節,存儲到 data 中。該方法返回實際讀取到的字節數。 |
qint64 QIODevice::write(const char *data, qint64 maxSize) | 向 data 數據一次性最多寫入 maxSize 個字節,該方法返回實際寫入的字節數。 |
qint64 QIODevice::write(const char *data) | 將 data 數據寫入文件,該方法返回實際寫入的字節數。 |
qint64 QIODevice::write(const QByteArray &byteArray) | 將 byteArray 數組中存儲的字節寫入文件,返回實際寫入的字節數。 |
bool QFile::copy(const QString &newName) | 將當前文件的內容拷貝到名為 newName 的文件中,如果成功,方法返回 true,否則返回 false。
copy 方法在執行復制操作之前,會關閉源文件。 |
bool QFile::rename(const QString &newName) | 對當前文件進行重命名,新名稱為 newName,成功返回 true,失敗返回 false。 |
bool QFile::remove() | 刪除當前文件,成功返回 true,失敗返回 false。 |
表 2 QFile常用方法
【實例一】演示瞭 QFile 類讀寫文本文件的過程。
#include <QFile> #include <QDebug> int main(int argc, char *argv[]) { //創建 QFile 對象,同時指定要操作的文件 QFile file("D:/demo.txt"); //對文件進行寫操作 if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){ qDebug()<<"文件打開失敗"; } //向文件中寫入兩行字符串 file.write("C語言中文網\n"); file.write("http://c.biancheng.net"); //關閉文件 file.close(); //重新打開文件,對文件進行讀操作 if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){ qDebug()<<"文件打開失敗"; } //每次都去文件中的一行,然後輸出讀取到的字符串 char * str = new char[100]; qint64 readNum = file.readLine(str,100); //當讀取出現錯誤(返回 -1)或者讀取到的字符數為 0 時,結束讀取 while((readNum !=0) && (readNum != -1)){ qDebug() << str; readNum = file.readLine(str,100); } file.close(); return 0; }
執行程序,”C語言中文網” 和 “http://c.biancheng.net” 先寫入 D 盤的 demo.txt 文件,然後再從文件中將它們讀取出來。
【實例二】演示 QFile 讀寫二進制文件的過程。
#include <QFile> #include <QDebug> int main(int argc, char *argv[]) { //指定要寫入文件的數據 qint32 nums[5]={1,2,3,4,5}; //寫入文件之前,要將數據以二進制方式存儲到字節數組中 QByteArray byteArr; byteArr.resize(sizeof(nums)); for(int i=0;i<5;i++){ //借助指針,將每個整數拷貝到字節數組中 memcpy(byteArr.data()+i*sizeof(qint32),&(nums[i]),sizeof(qint32)); } //將 byteArr 字節數組存儲到文件中 QFile file("D:/demo.dat"); file.open(QIODevice::WriteOnly); file.write(byteArr); file.close(); //再次打開文件,讀取文件中存儲的二進制數據 file.open(QIODevice::ReadOnly); QByteArray resArr = file.readAll(); //輸出讀取到的二進制數據 qDebug()<<"resArr: "<<resArr; //將二進制數據轉化為整數 char* data = resArr.data(); while(*data){ qDebug() << *(qint32*)data; data += sizeof(qint32); } return 0; }
執行程序,demo.dat 文件中會存儲 {1,2,3,4,5} 這 5 個整數的二進制形式,同時輸出以下內容:
resArr: “\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00”
1
2
3
4
5
單獨使用 QFile 類讀寫文件的過程既繁瑣又復雜,Qt 提供瞭兩個輔助類 QTextStream 和 QDataStream,前者用來讀寫文件文件,後者用來讀寫二進制文件,QFile 可以和它們搭配使用,從整體上提高讀寫文件的開發效率。
QFile+QTextStream
和單獨使用 QFile 類讀寫文本文件相比,QTextStream 類提供瞭很多讀寫文件相關的方法,還可以設定寫入到文件中的數據格式,比如對齊方式、寫入數字是否帶前綴等等。
使用 QTextStream 類之前,程序中要先引入<QTextStream>頭文件。QTextStream 類提供瞭很多種構造函數,常用的是:
QTextStream(QIODevice *device)
QIODevice 是 QFile 的父類,因此在構造 QTextStream 類的對象時,需要傳遞一個 QFile 類的對象。
下表羅列瞭 QTextStream 類常用的一些方法:
成員方法 | 功 能 |
---|---|
bool QTextStream::atEnd() const | 判斷是否讀到文件末尾,如果已經達到末尾,返回 true,否則返回 false。 |
QString QTextStream::read(qint64 maxlen) | 從文件中讀最多 maxlen 個字符,返回這些字符組成的 QString 字符串。 |
QString QTextStream::readAll() | 從文件中讀取所有內容,返回由讀取內容組成的 QString 字符串。 |
QString QTextStream::readLine(qint64 maxlen = 0) | 默認讀取一行文本,如果手動指定 maxlen 的值,則最多讀取 maxlen 個字符,並返回讀取內容組成的 QString 字符串。 |
void QTextStream::setFieldAlignment(FieldAlignment mode) | 設置對齊方式,通常與 setFieldWidth() 一起使用。 |
void QTextStream::setFieldWidth(int width) | 設置每份數據占用的位置寬度為 width。 |
表 3 QTextStream常用方法
QTextStream 類重載瞭>>輸入運算符和>>輸出運算符,使讀寫文本文件變得更簡單。例如,用 QTextStream 實現【實例一】的程序如下:
#include <QFile> #include <QDebug> #include <QString> #include <QTextStream> int main(int argc, char *argv[]) { //創建 QFile 對象,同時指定要操作的文件 QFile file("D:/demo.txt"); //對文件進行寫操作 if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){ qDebug()<<"文件打開失敗"; } QTextStream out(&file); //向文件中寫入兩行字符串 out << (QString)"C語言中文網\n" << (QString)"http://c.biancheng.net"; //關閉文件 file.close(); //重新打開文件,對文件進行讀操作 if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){ qDebug()<<"文件打開失敗"; } QTextStream in(&file); //一直讀,直至讀取失敗 while(!in.atEnd()){ QString str; //從文件中讀取一個字符串 in >> str; qDebug() << str; } file.close(); return 0; }
和<iostream>類似,QTextStream 類提供瞭兩種格式化輸出的方法,一種是調用該類的成員方法,例如表 3 中的 setFieldAlignment()、setFieldWidth 等,另一種是調用 QTextStream 類提供的格式描述符,下表羅列瞭常用的一些:
描述符 | 功能相同的方法 | 功 能 |
---|---|---|
Qt::hex | QTextStream::setIntegerBase(16) | 將指定整數對應的 16 進制數寫入到文件中。 |
Qt::showbase | QTextStream::setNumberFlags(numberFlags() | ShowBase) | 對於非十進制數,寫入到文件中時帶上相應的前綴。二進制數前綴是 0b,八進制數前綴是 0,十六進制數前綴是 0x。 |
Qt::forcesign | QTextStream::setNumberFlags(numberFlags() | ForceSign) | 將數字寫入文件時,帶上正負號。 |
Qt::fixed | QTextStream::setRealNumberNotation(FixedNotation) | 將浮點數以普通小數的形式寫入文件。 |
Qt::scientific | QTextStream::setRealNumberNotation(ScientificNotation) | 將浮點數以科學計數法的形式寫入文件。 |
Qt::left | QTextStream::setFieldAlignment(AlignLeft) | 左對齊 |
Qt::right | QTextStream::setFieldAlignment(AlignRight) | 右對齊 |
Qt::center | QTextStream::setFieldAlignment(AlignCenter) | 居中對齊 |
表 4 QTextStream常用格式描述符
舉個簡單的例子:
#include <QFile> #include <QDebug> #include <QString> #include <QTextStream> int main(int argc, char *argv[]) { QFile file("D:/demo.txt"); if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){ qDebug()<<"文件打開失敗"; } QTextStream out(&file); //將 10 的十六進制數寫入文件 out << hex << 10; //設置每份數據占用 10 個字符的位置 out.setFieldWidth(10); //以右對齊的方式寫入 3.14 out << left << 3.14; //後續數據以左對齊的方式寫入文件 out.setFieldAlignment(QTextStream::AlignRight); out << 2.7; //關閉文件 file.close(); return 0; }
程序運行後,demo.txt 存儲的文本內容為:
a3.14 2.7
QFile+QDataStream
QDataStream 類的用法和 QTextStream 非常類似,最主要的區別在於,QDataStream 用於讀寫二進制文件。
使用 QDataStream 類之前,程序中要引入<QDataStream>頭文件。創建 QDataStream 對象常用的構造函數為:
QDataStream::QDataStream(QIODevice *d)
下表羅列瞭 QDataStream 類常用的成員方法:
成員方法 | 功 能 |
---|---|
bool QDataStream::atEnd() const | 判斷是否讀到文件末尾,如果已經達到末尾,返回 true,否則返回 false。 |
QDataStream &QDataStream::readBytes(char *&s, uint &l) | 對於用 writeBytes() 方法寫入文件的 l 和 s,隻能使用 readBytes() 方法讀取出來。 |
int QDataStream::readRawData(char *s, int len) | 從文件中讀取最多 len 字節的數據到 s 中,返回值表示實際讀取的字節數。註意,調用該方法之前,需要先給 s 參數分配好內存空間。 |
void QDataStream::setVersion(int v) | 不同版本的 Qt 中,同名稱的數據類型也可能存在差異,通過調用此方法手動指定版本號,可以確保讀取數據的一致性。 |
int QDataStream::skipRawData(int len) | 跳過文件中的 len 個字節,返回實際跳過的字節數。 |
QDataStream &QDataStream::writeBytes(const char *s, uint len) | 將長度 len 和 s 一起寫入到文件中,對於 writeBytes() 寫入的數據,隻能用 readBytes() 方法讀取。 |
int QDataStream::writeRawData(const char *s, int len) | 將 s 中前 len 字節的數據寫入文件,返回值表示成功寫入的字節數。 |
表 5 QDataStream常用方法
QDataStream 類也對<<和>>進行瞭重載,舉個簡單的例子,用 QDataStream 重新實現實例二:
#include <QFile> #include <QDebug> #include <QDataStream> int main(int argc, char *argv[]) { //指定要寫入文件的數據 qint32 nums[5]={1,2,3,4,5}; QFile file("D:/demo.dat"); file.open(QIODevice::WriteOnly); //創建 QDataStream 對象 QDataStream out(&file); //將 nums 數組中的整數逐個寫入到二進制文件中 for(int i=0;i<5;i++){ out << nums[i]; } file.close(); //再次打開文件,讀取文件中存儲的二進制數據 file.open(QIODevice::ReadOnly); QDataStream in(&file); //讀取二進制文件中的數據 while(!in.atEnd()){ //每次讀取一個整數 qint32 num; in >> num; qDebug() << num; } return 0; }
輸出結果為:
1
2
3
4
5
到此這篇關於Qt QFile文件操作的具體使用的文章就介紹到這瞭,更多相關Qt QFile文件操作內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!