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

上一章我们介绍了有关二进制文件的读写。二进制文件比较小巧,却不是人可读的格式。而文本文件是一种人可读的文件。为了操作这种文件,我们需要使用QTextStream类。QTextStreamQDataStream的使用类似,只不过它是操作纯文本文件的。另外,像 XML、HTML 这种,虽然也是文本文件,可以由QTextStream生成,但 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;
}
1
2
3
4
5
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一致,但是读取时却会有些困难:

 
 
QFile data("file.txt");
if (data.open(QFile::ReadOnly)) {
QTextStream in(&data);
QString str;
int ans = 0;
in >> str >> ans;
}
1
2
3
4
5
6
7
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,如果我们需要使用另外的编码,可以使用

 
 
stream.setCodec("UTF-8");
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 的二进制形式,那么可以直接使用

 
 
out << bin << 12345678;
1
out << bin << 12345678;

就可以了。这等价于

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

更复杂的,如果我们想要舒服 1234567890 的带有前缀、全部字母大写的十六进制格式(0xBC614E),那么只要使用

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

即可。

不仅是QIODeviceQTextStream也可以直接把内容输出到QString。例如

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

这提供了一种简单的处理字符串内容的方法。

Qt 学习之路 2(37):文本文件读写的更多相关文章

  1. Qt 学习之路 2(21):事件过滤器

    Qt 学习之路 2(21):事件过滤器 豆子 2012年10月15日 Qt 学习之路 2 37条评论 有时候,对象需要查看.甚至要拦截发送到另外对象的事件.例如,对话框可能想要拦截按键事件,不让别的组 ...

  2. Qt 学习之路 2(36):二进制文件读写

    Qt 学习之路 2(36):二进制文件读写 豆子 2013年1月6日 Qt 学习之路 2 20条评论 在上一章中,我们介绍了有关QFile和QFileInfo两个类的使用.我们提到,QIODevice ...

  3. Qt 学习之路 2(17):文件对话框

    Home / Qt 学习之路 2 / Qt 学习之路 2(17):文件对话框 Qt 学习之路 2(17):文件对话框  豆子  2012年9月24日  Qt 学习之路 2  85条评论 在前面的章节中 ...

  4. 《Qt 学习之路 2》目录

    <Qt 学习之路 2>目录 <Qt 学习之路 2>目录  豆子  2012年8月23日  Qt 学习之路 2  177条评论 <Qt 学习之路 2>目录 序 Qt ...

  5. Qt 学习之路 2(72):线程和事件循环

    Qt 学习之路 2(72):线程和事件循环 <理解不清晰,不透彻>  --  有需求的话还需要进行专题学习  豆子  2013年11月24日  Qt 学习之路 2  34条评论 前面一章我 ...

  6. Qt 学习之路 2(71):线程简介

    Qt 学习之路 2(71):线程简介 豆子 2013年11月18日 Qt 学习之路 2 30条评论 前面我们讨论了有关进程以及进程间通讯的相关问题,现在我们开始讨论线程.事实上,现代的程序中,使用线程 ...

  7. Qt 学习之路 2(67):访问网络(3)

    Qt 学习之路 2(67):访问网络(3) 豆子 2013年11月5日 Qt 学习之路 2 16条评论 上一章我们了解了如何使用我们设计的NetWorker类实现我们所需要的网络操作.本章我们将继续完 ...

  8. Qt 学习之路 2(66):访问网络(2)

    Home / Qt 学习之路 2 / Qt 学习之路 2(66):访问网络(2) Qt 学习之路 2(66):访问网络(2)  豆子  2013年10月31日  Qt 学习之路 2  27条评论 上一 ...

  9. Qt 学习之路 2(64):使用 QJsonDocument 处理 JSON

    Home / Qt 学习之路 2 / Qt 学习之路 2(64):使用 QJsonDocument 处理 JSON Qt 学习之路 2(64):使用 QJsonDocument 处理 JSON  豆子 ...

随机推荐

  1. mysql中的自定义函数

    创建不带参数的自定义函数: 使用: 创建带参数的自定义函数: 使用: 创建具有复合结构的函数体的自定义函数:

  2. Spring总结十:事务案例

    数据库表Account: 导包: <dependencies> <!--测试--> <dependency> <groupId>junit</gr ...

  3. Gym - 101128C:Canvas Painting

    这个就是哈夫曼树哇~ 我们仨英语太差了,跟榜时候才看出来是哈夫曼树雾 一个优先队列就可以搞定 #include <cstdio> #include <algorithm> #i ...

  4. 【SQL Server数据迁移】把csv文件中的数据导入SQL Server的方法

    [sql] view plaincopy --1.修改系统参数 --修改高级参数 sp_configure 'show advanced options',1 go --允许即席分布式查询 sp_co ...

  5. 面试题:servlet jsp cook session 背1

    一.Servlet是什么?JSP是什么?它们的联系与区别是什么? Servlet是Java编写的运行在Servlet容器的服务端程序,狭义的Servlet是指Servlet接口,广义的Servlet是 ...

  6. linux下的同步与互斥

    linux下的同步与互斥 谈到linux的并发,必然涉及到线程之间的同步和互斥,linux主要为我们提供了几种实现线程间同步互斥的 机制,本文主要介绍互斥锁,条件变量和信号量.互斥锁和条件变量包含在p ...

  7. 为什么有时候在Windbg中下断点下不了呢??

    1.今天我发现我下断点的地方是我声明的变量,变量还仅仅是声明,没有赋值.因此不能下断点. 2.当不能下断点时,如何解决呢? (1)重启Vmware虚拟机.(2)在虚拟机中恢复“快照”.

  8. 网页中的foot底部定位问题

    有时候,我们会碰到这样一个问题. 网页底部一般有个foot对吧,放置一些友情链接版权声明什么的,这个模块是如何定位的? 要是直接放内容区域的下面的话,假如是内容区域的高度不够的话,那么foot下面是会 ...

  9. ssh试卷

    2.简述Hibernate的工作原理. 答:首先,Configuration读取Hibernate的配置文件及映射文件中的信息,即加载配置文件和映射文件,并通过Hibernate配置文件生成一个多线程 ...

  10. php系统常量

    (1)__FILE__ :php程序文件名.它可以帮助我们获取当前文件在服务器的物理位置. (2)__LINE__ :PHP程序文件行数.它可以告诉我们,当前代码在第几行. (3)PHP_VERSIO ...