Qt中Qfile類(lèi)的使用
1.引言
很多應(yīng)用程序都具備操作文件的能力,包括對(duì)文件進(jìn)行寫(xiě)入和讀取,創(chuàng)建和刪除文件等等,甚至某些應(yīng)用程序的就是為了操作文件,像WPS Office。基于此Qt框架中專(zhuān)門(mén)提供了對(duì)文件操作的類(lèi):QFile。
2.QFile文件操作
QFile類(lèi)支持對(duì)文件進(jìn)行讀取和寫(xiě)入,刪除,重命名,拷貝等常見(jiàn)的文件操作,它既可以操作文本文件,也可以用來(lái)操作二進(jìn)制文件。
在Qt代碼中我們使用QFIle類(lèi),需要先引入QFile的頭文件:#include <QFile>
。常見(jiàn)QFile類(lèi)對(duì)象時(shí),常見(jiàn)的構(gòu)造函數(shù)有:
QFile() QFile(QObject *parent)
參數(shù)parent
用來(lái)指定要操作的目標(biāo)文件,包含文件的存儲(chǔ)目錄和文件名,存儲(chǔ)路徑可以使用絕對(duì)地址(比如"D:/Demo/text.txt")或者相對(duì)路徑(比如"./Demo/text.txt")。路徑中的分隔符要用"/"表示。
通常情況下,我們一般調(diào)用第二個(gè)構(gòu)造函數(shù)來(lái)直接指明要操作的文件,對(duì)于第一個(gè)構(gòu)造函數(shù)而言,我們還需要調(diào)用 setFileName()
函數(shù)來(lái)指明要操作的文件。
與C++的讀寫(xiě)規(guī)則一樣,在對(duì)文件進(jìn)行相關(guān)操作之前,我們需要先打開(kāi)文件,打開(kāi)文件我們使用 open函數(shù)
。常用的語(yǔ)法格式為:
bool QFile::open(OpenMode Mode);
Mode參數(shù)表示不同的打開(kāi)方式,下列羅列了參數(shù)的可選值和及其不同的含義:
打開(kāi)模式 | 含義 |
---|---|
QIODevice::ReadOnly | 以只讀模式打開(kāi)文件。 |
QIODevice::WriteOnly | 以只寫(xiě)模式打開(kāi)文件。如果文件不存在,將創(chuàng)建新文件;如果文件已存在,其內(nèi)容將被清空。 |
QIODevice::ReadWrite | 以讀寫(xiě)模式打開(kāi)文件。 |
QIODevice::Append | 以追加模式打開(kāi)文件,寫(xiě)入的數(shù)據(jù)將追加到文件末尾,原有內(nèi)容保留。 |
QIODevice::Truncate | 打開(kāi)文件時(shí)清空其內(nèi)容。通常與 WriteOnly 或 ReadWrite 一起使用。 |
QIODevice::Text | 在文本模式下打開(kāi)文件,處理不同平臺(tái)的行結(jié)束符(如將 Windows 的 \r\n 轉(zhuǎn)換為 \n)。 |
QIODevice::Unbuffered | 以非緩沖模式打開(kāi)文件,數(shù)據(jù)將直接寫(xiě)入磁盤(pán)而不經(jīng)過(guò)緩沖區(qū)。 |
根據(jù)需要我們可以一次性選擇多個(gè)值,值和值之前使用 |
來(lái)進(jìn)行分割,比如:
- QIODevice::ReadOnly|QIODevice::Text表示只允許對(duì)文件進(jìn)行讀操作,讀取文件時(shí),會(huì)將行尾結(jié)束符轉(zhuǎn)換為 ‘\n’;
- QIODevice::WriteOnly|QIODevice::Text表示只允許對(duì)文件進(jìn)行寫(xiě)操作,將數(shù)據(jù)寫(xiě)入文件時(shí),會(huì)將行尾結(jié)束符轉(zhuǎn)換為本地格式;
- QIODevice::ReadWrite|QIODevice::Text| QIODevice::Append
但選擇的多個(gè)值之前不能相互沖突,比如比如 Append 和 Truncate 不能同時(shí)使用。
如果文件成功打開(kāi),open() 函數(shù)返回 true,否則返回 false。
QFile 類(lèi)提供了很多功能實(shí)用的方法,可以快速完成對(duì)文件的操作,下表列舉了常用的一些:
qint64 QFile::size() const | 獲取當(dāng)前文件的大小。對(duì)于打開(kāi)的文件,該方法返回文件中可以讀取的字節(jié)數(shù)。 |
---|---|
bool QIODevice::getChar(char *c) | 從文件中讀取一個(gè)字符,并存儲(chǔ)到 c 中。讀取成功時(shí),方法返回 true,否則返回 false。 |
bool QIODevice::putChar(char c) | 向文件中寫(xiě)入字符 c,成功時(shí)返回 true,否則返回 false。 |
QByteArray QIODevice::read(qint64 maxSize) | 從文件中一次性最多讀取 maxSize 個(gè)字節(jié),然后返回讀取到的字節(jié)。 |
qint64 QIODevice::read(char *data, qint64 maxSize) | 從文件中一次性對(duì)多讀取 maxSize 個(gè)字節(jié),讀取到的字節(jié)存儲(chǔ)到 data 指針指定的內(nèi)存控件中。該方法返回成功讀取到的字節(jié)數(shù)。 |
QByteArray QIODevice::readAll() | 讀取文件中所有的數(shù)據(jù)。 |
qint64 QIODevice::readLine(char *data, qint64 maxSize) | 每次從文件中讀取一行數(shù)據(jù)或者讀取最多 maxSize-1 個(gè)字節(jié),存儲(chǔ)到 data 中。該方法返回實(shí)際讀取到的字節(jié)數(shù)。 |
qint64 QIODevice::write(const char *data, qint64 maxSize) | 向 data 數(shù)據(jù)一次性最多寫(xiě)入 maxSize 個(gè)字節(jié),該方法返回實(shí)際寫(xiě)入的字節(jié)數(shù)。 |
qint64 QIODevice::write(const char *data) | 將 data 數(shù)據(jù)寫(xiě)入文件,該方法返回實(shí)際寫(xiě)入的字節(jié)數(shù)。 |
qint64 QIODevice::write(const QByteArray &byteArray) | 將 byteArray 數(shù)組中存儲(chǔ)的字節(jié)寫(xiě)入文件,返回實(shí)際寫(xiě)入的字節(jié)數(shù)。 |
bool QFile::copy(const QString &newName) | 將當(dāng)前文件的內(nèi)容拷貝到名為 newName 的文件中,如果成功,方法返回 true,否則返回 false。 copy 方法在執(zhí)行復(fù)制操作之前,會(huì)關(guān)閉源文件。 |
bool QFile::rename(const QString &newName) | 對(duì)當(dāng)前文件進(jìn)行重命名,新名稱(chēng)為 newName,成功返回 true,失敗返回 false。 |
bool QFile::remove() | 刪除當(dāng)前文件,成功返回 true,失敗返回 false。 |
3.演示示例
3.1實(shí)驗(yàn)一
演示了 QFile
類(lèi)讀寫(xiě)文本文件的過(guò)程
#include <QFile> #include <QDebug> int main(int argc, char *argv[]) { //創(chuàng)建 QFile 對(duì)象,同時(shí)指定要操作的文件 QFile file("D:/demo.txt"); //對(duì)文件進(jìn)行寫(xiě)操作 if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){ qDebug()<<"文件打開(kāi)失敗"; } //向文件中寫(xiě)入兩行字符串 file.write("hello\r\n"); file.write("world"); //關(guān)閉文件 file.close(); //重新打開(kāi)文件,對(duì)文件進(jìn)行讀操作 if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){ qDebug()<<"文件打開(kāi)失敗"; } //每次都去文件中的一行,然后輸出讀取到的字符串 char * str = new char[100]; qint64 readNum = file.readLine(str,100); //當(dāng)讀取出現(xiàn)錯(cuò)誤(返回 -1)或者讀取到的字符數(shù)為 0 時(shí),結(jié)束讀取 while((readNum !=0) && (readNum != -1)){ qDebug() << str; readNum = file.readLine(str,100); } file.close(); return 0; }
3.2實(shí)驗(yàn)二【演示 QFile 讀寫(xiě)二進(jìn)制文件的過(guò)程】
#include <QFile> #include <QDebug> int main(int argc, char *argv[]) { //指定要寫(xiě)入文件的數(shù)據(jù) qint32 nums[5]={1,2,3,4,5}; //寫(xiě)入文件之前,要將數(shù)據(jù)以二進(jìn)制方式存儲(chǔ)到字節(jié)數(shù)組中 QByteArray byteArr; byteArr.resize(sizeof(nums)); for(int i=0;i<5;i++){ //借助指針,將每個(gè)整數(shù)拷貝到字節(jié)數(shù)組中 memcpy(byteArr.data()+i*sizeof(qint32),&(nums[i]),sizeof(qint32)); } //將 byteArr 字節(jié)數(shù)組存儲(chǔ)到文件中 QFile file("D:/demo.dat"); file.open(QIODevice::WriteOnly); file.write(byteArr); file.close(); //再次打開(kāi)文件,讀取文件中存儲(chǔ)的二進(jìn)制數(shù)據(jù) file.open(QIODevice::ReadOnly); QByteArray resArr = file.readAll(); //輸出讀取到的二進(jìn)制數(shù)據(jù) qDebug()<<"resArr: "<<resArr; //將二進(jìn)制數(shù)據(jù)轉(zhuǎn)化為整數(shù) char* data = resArr.data(); while(*data){ qDebug() << *(qint32*)data; data += sizeof(qint32); } return 0; }
執(zhí)行程序,demo.dat 文件中會(huì)存儲(chǔ) {1,2,3,4,5} 這 5 個(gè)整數(shù)的二進(jìn)制形式,同時(shí)輸出以下內(nèi)容:
4.QFile+QTextStream
與單獨(dú)使用QFile類(lèi)相比,QTextStream類(lèi)提供了很多讀寫(xiě)文件相關(guān)的方法,還可以設(shè)定寫(xiě)入到文件的數(shù)據(jù)格式,比如對(duì)齊方式,寫(xiě)入數(shù)據(jù)是否帶前綴等等。
使用QTextStream類(lèi)之前,程序中需要先引入 頭文件。QTextStream提供了很多構(gòu)造方法,常用的是:
QTextStream(QIODevice *device)
QIODevice 是 QFile 的父類(lèi),因此在構(gòu)造 QTextStream 類(lèi)的對(duì)象時(shí),需要傳遞一個(gè) QFile 類(lèi)的對(duì)象。
下表羅列了 QTextStream 類(lèi)常用的一些方法:
bool QTextStream::atEnd() const | 判斷是否讀到文件末尾,如果已經(jīng)達(dá)到末尾,返回 true,否則返回 false。 |
---|---|
QString QTextStream::read(qint64 maxlen) | 從文件中讀最多 maxlen 個(gè)字符,返回這些字符組成的 QString 字符串。 |
QString QTextStream::readAll() | 從文件中讀取所有內(nèi)容,返回由讀取內(nèi)容組成的 QString 字符串。 |
QString QTextStream::readLine(qint64 maxlen = 0) | 默認(rèn)讀取一行文本,如果手動(dòng)指定 maxlen 的值,則最多讀取 maxlen 個(gè)字符,并返回讀取內(nèi)容組成的 QString 字符串。 |
void QTextStream::setFieldAlignment(FieldAlignment mode) | 設(shè)置對(duì)齊方式,通常與 setFieldWidth() 一起使用。 |
void QTextStream::setFieldWidth(int width) | 設(shè)置每份數(shù)據(jù)占用的位置寬度為 width。 |
QTextStream 類(lèi)重載了>>
輸入運(yùn)算符和>>
輸出運(yùn)算符,使讀寫(xiě)文本文件變得更簡(jiǎn)單。例如,用 QTextStream 實(shí)現(xiàn)【實(shí)例一】的程序如下:
#include <QFile> #include <QDebug> #include <QString> #include <QTextStream> int main(int argc, char *argv[]) { //創(chuàng)建 QFile 對(duì)象,同時(shí)指定要操作的文件 QFile file("D:/demo.txt"); //對(duì)文件進(jìn)行寫(xiě)操作 if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){ qDebug()<<"文件打開(kāi)失敗"; } QTextStream out(&file); //向文件中寫(xiě)入兩行字符串 out << (QString)"C語(yǔ)言中文網(wǎng)\n" << (QString)"http://c.biancheng.net"; //關(guān)閉文件 file.close(); //重新打開(kāi)文件,對(duì)文件進(jìn)行讀操作 if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){ qDebug()<<"文件打開(kāi)失敗"; } QTextStream in(&file); //一直讀,直至讀取失敗 while(!in.atEnd()){ QString str; //從文件中讀取一個(gè)字符串 in >> str; qDebug() << str; } file.close(); return 0; }
和<iostream>
類(lèi)似,QTextStream 類(lèi)提供了兩種格式化輸出的方法,一種是調(diào)用該類(lèi)的成員方法,例如表 3 中的 setFieldAlignment()、setFieldWidth 等,另一種是調(diào)用 QTextStream 類(lèi)提供的格式描述符,下表羅列了常用的一些:
描述符 | 功能相同的方法 | 功 能 |
---|---|---|
Qt::hex | QTextStream::setIntegerBase(16) | 將指定整數(shù)對(duì)應(yīng)的 16 進(jìn)制數(shù)寫(xiě)入到文件中。 |
Qt::showbase | QTextStream::setNumberFlags(numberFlags() | ShowBase) | 對(duì)于非十進(jìn)制數(shù),寫(xiě)入到文件中時(shí)帶上相應(yīng)的前綴。二進(jìn)制數(shù)前綴是 0b,八進(jìn)制數(shù)前綴是 0,十六進(jìn)制數(shù)前綴是 0x。 |
Qt::forcesign | QTextStream::setNumberFlags(numberFlags() | ForceSign) | 將數(shù)字寫(xiě)入文件時(shí),帶上正負(fù)號(hào)。 |
Qt::fixed | QTextStream::setRealNumberNotation(FixedNotation) | 將浮點(diǎn)數(shù)以普通小數(shù)的形式寫(xiě)入文件。 |
Qt::scientific | QTextStream::setRealNumberNotation(ScientificNotation) | 將浮點(diǎn)數(shù)以科學(xué)計(jì)數(shù)法的形式寫(xiě)入文件。 |
Qt::left | QTextStream::setFieldAlignment(AlignLeft) | 左對(duì)齊 |
Qt::right | QTextStream::setFieldAlignment(AlignRight) | 右對(duì)齊 |
Qt::center | QTextStream::setFieldAlignment(AlignCenter) | 居中對(duì)齊 |
程序運(yùn)行后,demo.txt 存儲(chǔ)的文本內(nèi)容為:
a3.14 2.7
5.QFile+QDataStream
QDataStream 類(lèi)的用法和 QTextStream 非常類(lèi)似,最主要的區(qū)別在于,QDataStream 用于讀寫(xiě)二進(jìn)制文件。
使用 QDataStream 類(lèi)之前,程序中要引入<QDataStream>
頭文件。創(chuàng)建 QDataStream 對(duì)象常用的構(gòu)造函數(shù)為:
QDataStream::QDataStream(QIODevice *d)
下表羅列了 QDataStream 類(lèi)常用的成員方法:
成員方法 | 功 能 |
---|---|
bool QDataStream::atEnd() const | 判斷是否讀到文件末尾,如果已經(jīng)達(dá)到末尾,返回 true,否則返回 false。 |
QDataStream &QDataStream::readBytes(char *&s, uint &l) | 對(duì)于用 writeBytes() 方法寫(xiě)入文件的 l 和 s,只能使用 readBytes() 方法讀取出來(lái)。 |
int QDataStream::readRawData(char *s, int len) | 從文件中讀取最多 len 字節(jié)的數(shù)據(jù)到 s 中,返回值表示實(shí)際讀取的字節(jié)數(shù)。注意,調(diào)用該方法之前,需要先給 s 參數(shù)分配好內(nèi)存空間。 |
void QDataStream::setVersion(int v) | 不同版本的 Qt 中,同名稱(chēng)的數(shù)據(jù)類(lèi)型也可能存在差異,通過(guò)調(diào)用此方法手動(dòng)指定版本號(hào),可以確保讀取數(shù)據(jù)的一致性。 |
int QDataStream::skipRawData(int len) | 跳過(guò)文件中的 len 個(gè)字節(jié),返回實(shí)際跳過(guò)的字節(jié)數(shù)。 |
QDataStream &QDataStream::writeBytes(const char *s, uint len) | 將長(zhǎng)度 len 和 s 一起寫(xiě)入到文件中,對(duì)于 writeBytes() 寫(xiě)入的數(shù)據(jù),只能用 readBytes() 方法讀取。 |
int QDataStream::writeRawData(const char *s, int len) | 將 s 中前 len 字節(jié)的數(shù)據(jù)寫(xiě)入文件,返回值表示成功寫(xiě)入的字節(jié)數(shù)。 |
QDataStream 類(lèi)也對(duì)<<
和>>
進(jìn)行了重載,舉個(gè)簡(jiǎn)單的例子,用 QDataStream 重新實(shí)現(xiàn)實(shí)例二:
#include <QFile> #include <QDebug> #include <QDataStream> int main(int argc, char *argv[]) { //指定要寫(xiě)入文件的數(shù)據(jù) qint32 nums[5]={1,2,3,4,5}; QFile file("D:/demo.dat"); file.open(QIODevice::WriteOnly); //創(chuàng)建 QDataStream 對(duì)象 QDataStream out(&file); //將 nums 數(shù)組中的整數(shù)逐個(gè)寫(xiě)入到二進(jìn)制文件中 for(int i=0;i<5;i++){ out << nums[i]; } file.close(); //再次打開(kāi)文件,讀取文件中存儲(chǔ)的二進(jìn)制數(shù)據(jù) file.open(QIODevice::ReadOnly); QDataStream in(&file); //讀取二進(jìn)制文件中的數(shù)據(jù) while(!in.atEnd()){ //每次讀取一個(gè)整數(shù) qint32 num; in >> num; qDebug() << num; } return 0; }
到此這篇關(guān)于Qt中Qfile類(lèi)的使用的文章就介紹到這了,更多相關(guān)Qt Qfile類(lèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
養(yǎng)成良好的C++編程習(xí)慣之內(nèi)存管理的應(yīng)用詳解
"養(yǎng)成良好的編程習(xí)慣"其實(shí)是相當(dāng)綜合的一個(gè)命題,可以從多個(gè)角度、維度和層次進(jìn)行論述和評(píng)判,如代碼的風(fēng)格、效率和可讀性;模塊設(shè)計(jì)的靈活性、可擴(kuò)展性和耦合度等等,要試圖把所有方面都闡述清楚必須花很多的精力,而且也不一定能闡述得全面2013-05-05Qt中樹(shù)形控件Tree Widget的使用方法匯總
最近小編在研究Tree Widget樹(shù)形控件的相關(guān)知識(shí),這種控件其實(shí)有時(shí)還是很有用處的,我主要利用的是帶有復(fù)選框的樹(shù)形控件,下面通過(guò)實(shí)例代碼給大家介紹下Qt中樹(shù)形控件Tree Widget的一些使用方法,感興趣的朋友一起學(xué)習(xí)吧2021-11-11C++動(dòng)態(tài)加載so/dll庫(kù)的實(shí)現(xiàn)
本文主要介紹了C++動(dòng)態(tài)加載so/dll庫(kù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-074組C語(yǔ)言中順序讀寫(xiě)文件的函數(shù)分享
這篇文章主要為大家詳細(xì)介紹了4組C語(yǔ)言中實(shí)現(xiàn)順序讀寫(xiě)文件的函數(shù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03VC++ 6.0 C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊詳細(xì)教程
這篇文章主要為大家介紹了VC++ 6.0 C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊詳細(xì)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06