Qt 學習之路 :文字檔讀寫

來源:互聯網
上載者:User

標籤:

 

上一章我們介紹了有關二進位檔案的讀寫。二進位檔案比較小巧,卻不是人可讀的格式。而文字檔是一種人可讀的檔案。為了操作這種檔案,我們需要使用QTextStream類。QTextStreamQDataStream的使用類似,只不過它是操作純文字檔案的。另外,像 XML、HTML 這種,雖然也是文字檔,可以由QTextStream產生,但 Qt 提供了更方便的 XML 操作類,這裡就不包括這部分內容了。

QTextStream會自動將 Unicode 編碼同作業系統的編碼進行轉換,這一操作對開發人員是透明的。它也會將分行符號進行轉換,同樣不需要自己處理。QTextStream使用 16 位的QChar作為基礎的資料存放區單位,同樣,它也支援 C++ 標準類型,如 int 等。實際上,這是將這種標準類型與字串進行了相互轉換。

 

QTextStreamQDataStream的使用基本一致,例如下面的代碼將把“The answer is 42”寫入到 file.txt 檔案中:

  
12345 QFile data("file.txt");if (data.open(QFile::WriteOnly | QIODevice::Truncate)) {    QTextStream out(&data);    out << "The answer is " << 42;}

這裡,我們在open()函數中增加了QIODevice::Truncate開啟檔案。我們可以從下表中看到這些開啟檔案的區別:

枚舉值 描述
QIODevice::NotOpen 未開啟
QIODevice::ReadOnly 以唯讀方式開啟
QIODevice::WriteOnly 以唯寫方式開啟
QIODevice::ReadWrite 以讀寫方式開啟
QIODevice::Append 以追加的方式開啟,新增加的內容將被追加到檔案末尾
QIODevice::Truncate 以重寫的方式開啟,在寫入新的資料時會將原有資料全部清除,遊標設定在檔案開頭。
QIODevice::Text 在讀取時,將行結束符轉換成 \n;在寫入時,將行結束符轉換成本地格式,例如 Win32 平台上是 \r\n
QIODevice::Unbuffered 忽略緩衝

我們在這裡使用了QFile::WriteOnly | QIODevice::Truncate,也就是以唯寫並且覆蓋已有內容的形式操作檔案。注意,QIODevice::Truncate會直接將檔案內容清空。

雖然QTextStream的寫入內容與QDataStream一致,但是讀取時卻會有些困難:

  
1234567 QFile data("file.txt");if (data.open(QFile::ReadOnly)) {    QTextStream in(&data);    QString str;    int ans = 0;    in >> str >> ans;}

在使用QDataStream的時候,這樣的代碼很方便,但是使用了QTextStream時卻有所不同:讀出的時候,str 裡面將是 The answer is 42,ans 是 0。這是因為以文本形式寫入資料,是沒有資料之間的分隔的。還記得我們前面曾經說過,使用QDataStream寫入的時候,實際上會在要寫入的內容前面,額外添加一個這段內容的長度值。而文字檔則沒有類似的操作。因此,使用文字檔時,很少會將其分割開來讀取,而是使用諸如QTextStream::readLine()讀取一行,使用QTextStream::readAll()讀取所有文本這種函數,之後再對獲得的QString對象進行處理。

預設情況下,QTextStream的編碼格式是 Unicode,如果我們需要使用另外的編碼,可以使用

  
1 stream.setCodec("UTF-8");

這樣的函數進行設定。

另外,為方便起見,QTextStreamstd::cout一樣提供了很多描述符,被稱為 stream manipulators。因為文字檔是供人去讀的,自然需要良好的格式(相比而言,二進位檔案就沒有這些問題,只要資料準確就可以了)。這些描述符是一些函數的簡寫,我們可以從文檔中找到:

描述符 等價於
bin setIntegerBase(2)
oct setIntegerBase(8)
dec setIntegerBase(10)
hex setIntegerBase(16)
showbase setNumberFlags(numberFlags() | ShowBase)
forcesign setNumberFlags(numberFlags() | ForceSign)
forcepoint setNumberFlags(numberFlags() | ForcePoint)
noshowbase setNumberFlags(numberFlags() & ~ShowBase)
noforcesign setNumberFlags(numberFlags() & ~ForceSign)
noforcepoint setNumberFlags(numberFlags() & ~ForcePoint)
uppercasebase setNumberFlags(numberFlags() | UppercaseBase)
uppercasedigits setNumberFlags(numberFlags() | UppercaseDigits)
lowercasebase setNumberFlags(numberFlags() & ~UppercaseBase)
lowercasedigits setNumberFlags(numberFlags() & ~UppercaseDigits)
fixed setRealNumberNotation(FixedNotation)
scientific setRealNumberNotation(ScientificNotation)
left setFieldAlignment(AlignLeft)
right setFieldAlignment(AlignRight)
center setFieldAlignment(AlignCenter)
endl operator<<(‘\n‘)flush()
flush flush()
reset reset()
ws skipWhiteSpace()
bom setGenerateByteOrderMark(true)

這些描述符只是一些函數的簡寫。例如,我們想要輸出 12345678 的二進位形式,那麼可以直接使用

  
1 out << bin << 12345678;

就可以了。這等價於

  
12 out.setIntegerBase(2);out << 12345678;

更複雜的,如果我們想要舒服 1234567890 的帶有首碼、全部字母大寫的十六進位格式(0xBC614E),那麼只要使用

  
1 out << showbase << uppercasedigits << hex << 12345678;

即可。

不僅是QIODeviceQTextStream也可以直接把內容輸出到QString。例如

  
12 QString str;  QTextStream(&str) << oct << 31 << " " << dec << 25 << endl;

這提供了一種簡單的處理字串內容的方法。

Qt 學習之路 :文字檔讀寫

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.