QFile
Qt中所有與IO相關的類都繼承於QIODevice,繼承圖如下所示:
其中QFile類便是用於文件操作的類
在QT中,將文件當做一種特殊的外部設備對待(比如:串口,usb等就是外部設備)
QT中,IO操作相關的函數接口,常用以下幾種
打開設備
bool open(OpenMode mode); //打開文件成功返回true,否則返回false // mode有: // QIODevice::ReadOnly 、QIODevice::WriteOnly、QIODevice::ReadWrite // QIODevice::Append :寫入的數據將會寫在文件末尾 // QIODevice::Truncate :打開文件后,之前的內容將會消失(默認Truncate是打開的) //QIODevice::Text:以文本方式寫入(若寫"\n",在win平台上則自動被翻譯為"\r\n"),否則以數據方式寫入(寫入的是字節)
讀取數據
QByteArray read(qint64 maxSize) //從設備讀取最多maxSize字節的數據 , QByteArray 類可以默認轉換為QString類 QByteArray readAll(); //讀出所有數據 qint64 readData ( char * data, qint64 maxSize ); //讀出最多maxSize字節的數據,送到char * data里, 並返回成功寫入的字節數,失敗則返回-1 QByteArray QIODevice::readLine ( qint64 maxSize = 0 ); //讀出一行數據
寫入數據
qint64 write(const QByteArray & byteArray) //將byteArray寫入設備,返回成功寫入的字節數,失敗則返回-1 qint64 writeData ( const char * data, qint64 len ); //從char * data里寫入最多len字節的數據到設備, 並返回成功寫入的字節數,失敗則返回-1
關閉設備
void close();
- IO操作的本質是讀寫連續的存儲空間數據
QT中,存取IO設備分為兩種
-順序存取設備(比如:串口)
只能從頭開始順序的讀寫數據,不能指定數據的讀寫位置
-隨機存取設備(比如:文件)
可以隨機定位到任意位置,進行數據讀寫,通過seek()函數實現
QFile文本文件操作示例
在Qt中,一個QFile對象便對應着一個文件
QFile file file("C:/Users/Administrator/Desktop/test.txt"); //創建文件對象 /*寫數據*/ if( file.open(QIODevice::WriteOnly | QIODevice::Text) ) { file.write("D.T.Software\n"); file.write("Delphi Tang\n"); file.close(); } /*讀數據*/ if( file.open(QIODevice::ReadOnly | QIODevice::Text) ) { QByteArray ba = file.readLine(); QString s(ba); //將字節數組轉換為字符串 qDebug() << s; file.close(); }
QFileInfo類(獲取文件屬性信息)
示例:
QFile file("C:/Users/Administrator/Desktop/test.txt"); QFileInfo info(file); qDebug() << info.exists(); //判斷文件是否存在 qDebug() << info.isFile(); //判斷這個路徑是文件,還是文件夾 qDebug() << info.isReadable(); //該文件是否可讀 qDebug() << info.isWritable(); //該文件是否可寫 qDebug() << info.created(); //返回創建該文件的時間 qDebug() << info.lastRead(); //返回最后訪問文件的時間 qDebug() << info.lastModified(); //返回最后修改文件的時間 qDebug() << info.absolutePath(); //返回該文件的目錄絕對路徑 qDebug() << info.fileName(); //返回該文件名稱 qDebug() << info.suffix(); //返回該文件后綴 qDebug() << info.size(); //返回文件大小 qDebug() << info.absoluteFilePath(); //返回該絕對路徑
打印:
true true true true
QDateTime("周三 五月 2 09:01:04 2018") QDateTime("周三 五月 2 09:01:04 2018") QDateTime("周三 五月 2 09:02:33 2018") "C:/Users/Administrator/Desktop" "test.txt" "txt" 27 "C:/Users/Administrator/Desktop/test.txt"
QFile數據文件操作示例:
由於write和read函數只能支持char參數,如果填入數值型或QSTring型時,則需要轉換:
QString str="哈哈達"; QFile file("C:/Users/Administrator/Desktop/test.hex"); /*寫數據*/ if( file.open( QIODevice::WriteOnly ) ) { double i=3.1412; file.write(str.toStdString().c_str()); //QString->string->char file.write(reinterpret_cast<char *>(&i),sizeof(i)); //寫入8字節數據(數值) file.close(); } /*讀數據*/ if( file.open(QIODevice::ReadOnly) ) { QString s = file.read(str.toStdString().length()); qDebug() << s; double value; file.read(reinterpret_cast<char *>(&value),sizeof(value)); //讀出double qDebug() << value; file.close(); }
這樣轉換會顯得非常麻煩,所以QT提供了輔助類來簡化文本文件/數據文件的讀寫
QTextStream、QDataStream輔助類
QTextStream
將寫入的數據全部轉換為可讀文本(適用於文本文件)
QDataStream
將寫入的數據根據類型轉換為二進制數據(適用於數據文件)
注意
QDataStream在不同版本中,數據格式可能不同,所以數據文件如果要在不同版本QT程序間傳遞,還需要考慮版本問題:
void setVersion(int v); //設置讀寫版本號,比如4.7版本,則填入: QDataStream::Qt_4_7 int version(); //獲取讀寫版本號
QTextStream使用示例
QFile file("C:/Users/Administrator/Desktop/test.txt");
/*寫數據*/ if( file.open( QIODevice::WriteOnly| QIODevice::Text ) ) { QTextStream out(&file); //定義out對象,通過<<操作符向設備輸出數據 out << QString("D.T.Software ")<<endl ; //將QString自動轉為字符 out << QString("哈哈達") << endl; out << 5 << '*' << 6 << '=' << 5 * 6 << endl; //將數值自動轉為字符 file.close(); } /*讀數據*/ if( file.open(QIODevice::ReadOnly| QIODevice::Text) ) { QTextStream in(&file); //定義in對象,通過>>操作符從設備讀數據 while( !in.atEnd() ) { QString str; in>>str; qDebug()<<str; //打印3次 } file.close(); }
注意: endl其實只是加了\n,由於win平台的換行符是\r\n,所以需要加上QIODevice::Text,QT便會自動將\n轉為\r\n.
QDataStream使用示例
QFile file("C:/Users/Administrator/Desktop/test.txt"); if( file.open(QIODevice::WriteOnly) ) { QDataStream out(&file); out.setVersion(QDataStream::Qt_4_7); //設置版本 out << QString("D.T.Software"); out << QString("Result: "); out << 3.14; file.close(); } if( file.open(QIODevice::ReadOnly) ) { QDataStream in(&file); QString dt = ""; QString result = ""; double value = 0; in.setVersion(QDataStream::Qt_4_7); ////設置版本 in >> dt; in >> result; in >> value; qDebug() << dt; qDebug() << result; qDebug() << value; file.close(); }
QBuffer緩沖區
緩沖區的本質為一段連續的存儲空間
- 緩存區分為內部和外部,外部設備便表示外部緩沖區,而 QBuffer類則表示計算機的內部緩沖區
- 在Qt中可以將緩沖區看作一種特殊的IO設備
- QTextStream,QDataStream文件流輔助類也可以直接用於操作緩沖區
QBuffer緩沖區的使用場合
- 通過進程間共享緩沖區,實現線程間不同類型的數據傳遞
- 可以緩沖外部設備的讀寫數據,比如串口數據
- 當數據讀取速度小於寫入速度時
QBuffer使用方法:
QByteArray array; QBuffer buffer(&array); if(buffer.open(QIODevice::WriteOnly)) { QDataStream out(&buffer); out << QString("3.1234"); out << QString("scorpio"); out << QString("1234"); out << 1.34; buffer.close(); } if(buffer.open(QIODevice::ReadOnly)) { QDataStream in(&buffer); QString name; QString a; QString b; double num; in >> a; in >> name; in >> b; in >> num; qDebug() << name; qDebug() << a; qDebug() << b; qDebug() <<num; buffer.close(); }
QDir目錄
QT中提供了目錄操作類QDir,QDir功能如下:
- 目錄分隔符統一使用’/’
- 能夠對目錄進行任意操作(創建、刪除、重命名)
- 能夠獲取指定目錄中的所有條目(文件和文件夾)
- 能夠使用過濾字符串獲取指定條目
- 能夠獲取系統中的所有根目錄
QDir使用方法如下:
QDir dir; QString path = ("C:/Users/Administrator/Desktop/QDir"); if(!dir.exists(path)) { dir.mkdir(path); } else { dir.cd(path); QStringList filters; //字符串列表,用來篩選文件條目 filters << "*.bmp" << "*.png"; QStringList list = dir.entryList(filters,QDir::NoDotAndDotDot|QDir::AllEntries); // QDir::NoDotAndDotDot:不要出現.和..兩個條目, QDir::AllEntries:所有(文件,目錄等) for(int i = 0; i < list.count(); i++) { qDebug() << list[i]; } }
來個示例,寫個函數用來讀取當前目錄/或者文件的大小:
int Calculate_Size(QString PATH) { int size=0; QFileInfo file(PATH); if(file.isFile()) { return file.size(); } else if(file.isDir()) { QDir dir(PATH); QFileInfoList files = dir.entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries); qDebug()<<files.length(); for(int i=0;i<files.length();i++) { qDebug()<<files[i].absoluteFilePath(); size+=Calculate_Size(files[i].absoluteFilePath()); //遞歸地查找 } } return size; }
QFileSystemWatcher文件系統監視
用來監控目錄或文件的狀態變化
- 能夠同時對多個目錄/文件進行監控
- 當目錄或文件發生改變時,將會觸發信號
- 可以通過信號與槽的機制捕捉信號,並做出響應
QFileSystemWatcher信號函數如下所示:
void directoryChanged ( const QString & path ); //當指定的目錄被修改(例如該目錄里一個文件被添加、修改或刪除或從磁盤刪除時),這個信號就會發出。 void ileChanged ( const QString & path ); //當指定的文件被修改、重命名或從磁盤刪除時,就會發出這個信號
示例
QFsWatcher.h:
#ifndef QFSWATCHER_H #define QFSWATCHER_H
#include <QObject> #include <QFileSystemWatcher> #include <QDebug> class QFsWatcher : public QObject { Q_OBJECT private : QFileSystemWatcher fs; private slots: void Dir_status( const QString & path ); void File_status( const QString & path ); public: explicit QFsWatcher(QObject *parent = 0); void addPath(const QString & path); }; #endif // QFSWATCHER_H
QFsWatcher.cpp:
#include "QFsWatcher.h" QFsWatcher::QFsWatcher(QObject *parent) : QObject(parent) { connect(&fs,SIGNAL(directoryChanged(const QString&)),this,SLOT(Dir_status(const QString&)) ); connect(&fs,SIGNAL(fileChanged(const QString&)),this,SLOT(File_status(const QString&)) ); } void QFsWatcher::Dir_status( const QString & path ) { qDebug()<<path<<": is Changed!"; } void QFsWatcher::File_status( const QString & path ) { qDebug()<<path<<": is Changed!"; } void QFsWatcher::addPath(const QString & path) { fs.addPath(path); }
main.cpp:
#include <QtCore/QCoreApplication> #include "QFsWatcher.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QFsWatcher watcher; watcher.addPath("C:/Users/Administrator/Desktop/QDir"); //監視QDir目錄 watcher.addPath("C:/Users/Administrator/Desktop/text.txt"); //監視text.txt文件 return a.exec(); }
效果: