Qt 学习之路 2(37):文本文件读写

QTextStream类。QTextStreamQDataStreamQTextStream生成,但 Qt 提供了更方便的 XML 操作类,这里就不包括这部分内容了。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 平台上是 rn
QIODevice::Unbuffered    忽略缓存
我们在这里使用了QFile::WriteOnly | QIODevice::Truncate,也就是以只写并且覆盖已有内容的形式操作文件。注意,QIODevice::Truncate会直接将文件内容清空。虽然QTextStream的写入内容与QDataStream一致,但是读取时却会有些困难:
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。这是因为以文本形式写入数据,是没有数据之间的分隔的。还记得我们前面曾经说过,使用QDataStreamQTextStream::readLine()读取一行,使用QTextStream::readAll()读取所有文本这种函数,之后再对获得的QString对象进行处理。默认情况下,QTextStream的编码格式是 Unicode,如果我们需要使用另外的编码,可以使用
stream.setCodec("UTF-8");
这样的函数进行设置。另外,为方便起见,QTextStreamstd::cout
描述符    等价于
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;
这提供了一种简单的处理字符串内容的方法。

相关内容推荐