Qt 檔案處理

來源:互聯網
上載者:User

Qt提供了QFile類來進行檔案處理,為了更方便地處理文字檔或二進位檔案,Qt還提了QTextStream類和QDataStream類,處理臨時檔案可以使用QTemporaryFile,擷取檔案資訊可以使用QFileInfo
,處理目錄可以使用QDir.監視檔案和目錄變化可以使用QFileSystemWatcher.

讀寫文字檔
QFile類提供了讀寫檔案的介面,QFile類可以讀寫文字檔,二進位檔案和Qt資源檔,也可以使用更方便的QTextStream,QDataStream類讀取文字檔和二進位檔案,要開啟一個檔案,可以在建構函式中指定檔案名稱,也可以在任何時候使用setFileName()函數設定檔案名稱,開啟檔案使用open函數,關閉檔案使用close函數。QFile中可以使用QIODevice中繼承的readLine()函數讀寫文字檔的一行。如:
  QFile file("zeki.txt");
  if(file.open(QIODevice::ReadOnly))
  {
      char buffer[2048];
      qint 64 lineLen=file.readLine(buffer,sizeof(buffer));
      if(lineLen!=-1)
      {
         qDebug<       }
  }
如果讀取成功,readLine返回實際讀取的位元組數,如果讀取失敗則返回-1
QTextStream提供了更為方便的介面來讀寫文本,QTextStream可以操作QIODevice,QByteArray,QString.QTextStream使用流操作符,可以方便地讀寫單詞,行和數字。為了產生文本,QTextStream提供了填充,對齊和數字格式化的格式選項。如
   QFile data("test.txt");
   if(data.open(QFile::WriteOnly|QFile::Truncate))
   {
        QTextStream out(&data);
        out<    }
  
QTextStream的格式化函數
----------------------------------------------
qSetFieldWidth(int width)  設定欄位寬度
qSetPadChar(QChar ch)      設定填充字元
qSetRealNumberPrecision(int precision) 設定實數精度
----------------------------------------------
在QTextStream中使用的預設編碼是QTextCodec::codecForLocal()函數返回的編碼,同時能夠自動檢測Unicode。也可以使用QTextStream::setCodec(QTextCodec *codec)函數設定的流編碼。

操作二進位檔案
QDataStream類提供了將二進位檔案序列化的功能,QDataStream實現了c++基礎資料型別 (Elementary Data Type)的序列化,如char,short,int char* 更複雜的資料類型序列化通過將資料類型分解為基本的資料類型來完成。下面用來寫位元據到資料流。
QFile file("binary.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out< out<<(qint32)42<<(qint32)96;
將上面寫入的檔案讀入的過程為:
QFile file("binary.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QString str;
qint32 x,y;
in>>str>>x>>y;
每一個條目都可以定義的二進位格式寫入檔案,Qt中的很多類型,包括QBrush,QColor,QDateTime,QFont,QPixmap,QString,QVariant等都可以寫入資料流。

如果需要讀取未經處理資料,可以使用readRawData()讀取資料到預先定義好的char *緩衝區,寫未經處理資料使用writeData(),讀寫未經處理資料需要對資料進行編碼和解碼。
下面例子示範了使用QDataStream進行讀寫檔案的過程。
#include
#include
using namespace std;
int main(int argc,char **argv)
{
   QCoreApplication app(argc,argv);
   QFile file("binary.file");
   file.open(QIODevice::WriteOnly|QIODevice::Truncate);
   QDataStream out(&file);
   out<    out<    out<<(qint32)21;
   file.close();
  
   file.setFileName("binary.file");
   if(!ifle.open(QIODevice::ReadOnly))
   {
      cout<<"開啟檔案錯誤!";
      return 1;
   }
   QDataStream in(&file);
   QString name;
   QDate birthday;
   qint32 age;
   in>>name>>birthday>>age;
      qDebug()<       cout<       qPrintable(birthday.toString("yyyy MMMM dd dddd"));
   file.close();
   return 0;
}
在例子中,QDataStream類寫入了姓名(QString),生日(QDate),和年齡(qint32)三個資料,讀取時使用相同的類型讀出。QDataStream可以讀取任意以QIODevice為基類產生的對象產生的資料。如QTcpSocket,QUdpSocket,QBuffer,QFile,QProcess等類的資料。可以使用QDataStream在QAbstractSocket一端寫入資料,另一端使用QDataStream讀取資料,這樣就免去了繁瑣的
高低端位元組轉換過程。
臨時檔案
實際應用中有時可能需要使用臨時檔案,Qt中提供QTemporaryFile類來提供臨時檔案。QTemporayFile可以安全地建立一個第一無二的臨時檔案。臨時檔案通過open()來建立。Qt可以保證臨時檔案不會重複。在臨時檔案對象銷毀後,將自動刪除該臨時檔案。臨時檔案通過close()關閉後還可以開啟,只要臨時檔案對象還沒有銷毀,臨時檔案就一直存在並由QTemporaryFile內部保持開啟。系統的臨時目錄可以通過QDir::tempPath()來擷取,unix/linux系統上的臨時目錄通常時/temp在windows上通常是TEM/TMP指定

目錄操作和檔案管理
QDir類具有存取目錄結構和內容的能力。使用QDir可以操作目錄,存取目錄或檔案資訊,操作底層檔案系統,而且還可以存取Qt的資源檔。Qt使用/作為通用的目錄分割符和URL路徑分隔字元。Qt可以使用相對路徑和絕對路徑指向一個檔案,isRelative()和isAbsolute()函數可以判斷QDir對象使用的是相對路徑還是絕對路徑。將相對路徑轉換為絕對路徑使用makeAbsolute()函數。目錄路徑可以通過path()函數返回,通過setPath()函數設定新路徑,絕對路徑使用absolutePath()返回。目錄名可以使用dirName()返回。目錄的路徑可以通過cd() cdUp()改變,可以使用mkdir()建立目錄,rename()改變目錄名。判斷目錄是否存在可以使用exists(),目錄的屬性可以使用 isReadable(),isAbsolute(),isRelative()和isRoot()來擷取,目錄下有很多條目,包括檔案,目錄和符號連結,總的條目數可以使用count()來統計。entryList()可以返回目錄下所有條目組成的字串鏈表,檔案可以使用remove()函數刪除,rmdir()刪除目錄。
linux du命令

int main(int argc, char **argv)
{
   QCoreApplication app(argc,argv);
   QStringList args=app.arguments();
   QString path;
   if(args.count()>1)
     path=args[1];
   else
     path=QDir::currentPath();
   qDebug()<    du(path);
   return 0;
}
qint64 du(const QString &path)
{
    QDir dir(path);
    qint64 size=0;
    foreach(QFileInfo fileInfo,dir.entryInfoList(QDir::Files))
       size+=fileInfo.size();
    foreach(QString subDir,dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot))
       size+=du(path+Dir::separator()+subDir);
    char unit=///'B///';
    if(curSize>1024)
    {
       curSize/=1024;
       unit=///'K///';
       if(curSize>1024)
       {
          curSize/=1024;
          unit=///'M///';
          if(curSize>1024)
          {
            curSize/=1024;
            unit=///'G///';
          }
        }
     }
     cout<      return size;
}
函數du()中,entryInfoList(QDir::Files)函數返迴文件資訊,然後根據這些資訊計算檔案大小,接下來判斷是否有子目錄,如果有則遞迴計算。dir.etnryList(QDir::Dirs|QDir::NoDotAndDotDot)返回所有子目錄並過濾掉. .. 目錄。由於windows(),linux平台/ /差異,使用QDir::separator()函數來返回特定平台的目錄分隔字元。另外QDirIterator可以完成
枚舉目錄的功能,Qt4.3還引入了檔案搜尋首碼的概念,檔案搜尋首碼時至少由兩個字元組成,用來搜尋指定檔案的路徑。
QDir::setSearchPaths("docs",QStringList("c:/My Docments"));
QDir::addSearchPaht("Docs",QStringList("D:|Documents"));
QFile file("docs::qt4.doc");
這樣就可以在兩個目錄中尋找。

檔案管理
QFileInfo類提供了與系統無關的檔案信心,它能提供文明名和路徑,存取許可權,以及檔案是否為目錄或符號連結,檔案大小,以及最後修改/讀取的時間等。QFileInfo也能從資源中擷取資訊。QFileInfo可以使用相對路徑或絕對路徑。檔案名稱可以在QFileInfo的建構函式中傳遞,也可以使用setFile()函數指定,要判斷一個函數是否存在,使用exits()函數,檔案大小可以通過size()函數擷取,檔案類型可以通過isFile(),isDir(),isSymLink()來擷取,symLinkTarget()函數返回符號連結所指向的真本文件名。QFileInfo提供refresh函數重新整理檔案資訊,如果需要QFileInfo每次從檔案系統讀取資訊,二不是從緩衝讀取,可以使用setCaching(false)關閉緩衝。檔案名稱和目錄可以通過path()和fileName()分解,fileName()返回的部分可以通過baseName()和extension()來獲得主檔案名和擴充檔案名稱,檔案的操作日期可以通過created(),lastModified()和lastRead()擷取,檔案的存取許可權可通國isReadable,isWriteable(),isExcutetable()擷取,檔案的屬主可以通過owner(),ownerId,group(),groupId()擷取,檔案的許可權和屬主也可以通過 permission()一起讀取。

監視檔案系統的變化
在Qt中可以使用QFileSystemWatcher類來監視檔案和目錄的改變.使用addPath()函數來監視指定的檔案和目錄,如果需要監視多個目錄,使用addPaths()來加入監視,如果要一處不需要監視的目錄,可以使用removePath(),removePaths()函數.當監視的檔案被修改或刪除時,產生一個fileChanged()訊號,如果被監視的目錄被修改或刪除,產生directoryChanged()訊號,下例實現了監視指定目錄的功能.
#include
#include
#include
#Include"Msg.h"
using namespace std;
int main(int argc,char **argv)
{
    QApplication app(argc,argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForLocale())
   
    Msg msg;
    msg.show();
    return app.exec();
}
Msg::Msg()
{
   QFont font;
   font.setPointSize(24);
   setFont(font);
   QStringList args=qApp->arguments();
   QString path;
   if(args.count()>1)
     path=args[1];
   else
     path=QDir::currentPath();
   label=new QLabel();
   label->setText(tr("監視的目錄:")+path);
  
   QVBoxLayout *layout=new QVBoxLayout;
   layout->addWidget(label);
   setLayout(layout);
  
   fsWatcher.addPath(path);
   connect(&fsWatcher,SIGNAL(directoryChanged(QString)),this,SLOT(directoryChanged(QString)));
}
在建構函式中讀取命令指定的目錄作為監視目錄,如果沒有指定則監視目前的目錄,使用connect()函數將目錄的directroyChanged()訊號和響應函數串連.
void Msg::directoryChanged(QString path)
{
    QMessageBox::information(NULL,tr("目錄變化"),path);
}

檔案引擎
Qt的QtDir,QFile,QFileInfo類在內部都使用一個類,QAbstractFileEngine.通過繼承QAbstractFileEngine類,可以編寫自己的檔案處理函數,然後繼承QAbstractFileEngineHander類註冊自己的檔案引擎,然後這樣就可以使用自己的檔案讀取引擎了.QAbstractFileEngineHandler是建立QAbstractFileEngine的類工廠.當開啟一個檔案時,Qt通過內部註冊的檔案引擎鏈表,選擇合適的檔案引擎並建立相應的引擎對象.為了安裝一個特定的檔案引擎,必須繼承QAbstractFileEngineHandler並實現create()函數.執行個體化引擎時Qt自動註冊該引擎,最後註冊的引擎比之前註冊的優先順序高.
如果想讀取tar檔案的引擎,可以從QAbstractFileEngineHandler類繼承
class TarEngineHandler:public QAbstractFileEngineHandler
{
    public:
        QAbstractFileEngine *create(const QString &fileName) const;
};
create()函數返回TarEngine對象,TarEngine是檔案引擎,時真正的檔案處理類.
QAbstractFileEngine *TarEngineHandler::create(const QString &fileName) const
{
    return fileName.toLower().endsWith(".tar")?new TarEngine(fileName):0;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.