【Qt筆記】文本文件讀寫

上一章咱們介紹了有關二進制文件的讀寫。二進制文件比較小巧,卻不是人可讀的格式。而文本文件是一種人可讀的文件。爲了操做這種文件,咱們須要使用QTextStream類。QTextStreamQDataStream的使用相似,只不過它是操做純文本文件的。另外,像 XML、HTML 這種,雖然也是文本文件,能夠由QTextStream生成,但 Qt 提供了更方便的 XML 操做類,這裏就不包括這部份內容了。git

QTextStream會自動將 Unicode 編碼同操做系統的編碼進行轉換,這一操做對開發人員是透明的。它也會將換行符進行轉換,一樣不須要本身處理。QTextStream使用 16 位的QChar做爲基礎的數據存儲單位,一樣,它也支持 C++ 標準類型,如 int 等。實際上,這是將這種標準類型與字符串進行了相互轉換。緩存

 

QTextStreamQDataStream的使用基本一致,例以下面的代碼將把「The answer is 42」寫入到 file.txt 文件中:函數

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一致,可是讀取時卻會有些困難:code

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,若是咱們須要使用另外的編碼,可使用ip

stream.setCodec("UTF-8");

這樣的函數進行設置。ci

另外,爲方便起見,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 的二進制形式,那麼能夠直接使用

out << bin << 12345678;

就能夠了。這等價於

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

更復雜的,若是咱們想要舒服 1234567890 的帶有前綴、所有字母大寫的十六進制格式(0xBC614E),那麼只要使用

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

便可。

不只是QIODeviceQTextStream也能夠直接把內容輸出到QString。例如

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

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

相關文章
相關標籤/搜索