14.QT-QFile文件,QBuffer緩沖區,QDir目錄,QFileSystemWatcher文件系統監視


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();
}

效果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM