系列文章目录
文章目录
前言
QTextStream类是Qt框架中用于读写文本的类。它可以方便地读取和写入各种类型的数据,如字符串、整数、浮点数等。QTextStream类可以与文件、字符串、标准输入输出设备等进行交互,并且支持读取和写入不同的编码格式。
一、概述
1.1 QTextStream类
QTextStream类是Qt中的一个用于读写文本数据的工具类。 它提供了简单而方便的接口,可以以流的方式读取和写入文本数据。QTextStream可以与任何QIODevice(如文件、套接字、字符串等)一起使用,并支持不同的编码格式。
使用QTextStream可以实现文本文件的读取和写入,也可以将文本数据插入到字符串中,或者从字符串中读取文本数据。它还提供了一些方便的方法,可以按行读取和写入文本数据,或者将文本数据按照指定的分隔符进行分割和合并。
QTextStream类是Qt的IO模块中的一部分,它被广泛用于Qt应用程序中进行文本数据的处理和操作。
1.2 QTextStream类的作用和用途
-
读取和写入文本文件: 可以使用QTextStream读取和写入文本文件,支持不同的编码格式。通过使用QFile或QIODevice来打开文件,并将其传递给QTextStream,可以轻松地读取和写入文本文件的内容。
-
字符串的读写: QTextStream可以将字符数据读取到字符串中,也可以将字符串写入到流中。这对于处理内存中的字符串数据非常有用,可以在内存中进行文本操作而不用进行实际的文件读写。
-
流式操作: QTextStream提供了方便的流式操作,可以按照特定的分隔符将文本数据分割成单独的部分,或者将多个部分合并成一个字符串。这对于解析和拼接文本数据非常有用。
-
行操作: QTextStream提供了逐行读取和写入文本数据的方法,方便处理大型的文本文件。可以使用readLine()方法逐行读取文件,或者使用writeLine()方法将字符串以行的形式写入文件。
-
格式化输出: QTextStream提供了方便的格式化输出功能,可以将不同类型的数据格式化为字符串并写入流中。例如,可以使用<<操作符将整数、浮点数等数据直接写入流中,而无需手动转换为字符串。
二、基本用法
2.1 QTextStream成员函数
函数 | 描述 |
---|---|
bool QTextStream::atEnd() const | 判断是否读到文件末尾,如果已经达到末尾,返回 true,否则返回 false。 |
QString QTextStream::read(qint64 maxlen) | 从文件中读最多 maxlen 个字符,返回这些字符组成的 QString 字符串。 |
QString QTextStream::readAll() | 从文件中读取所有内容,返回由读取内容组成的 QString 字符串。 |
QString QTextStream::readLine(qint64 maxlen = 0) | 默认读取一行文本,如果手动指定 maxlen 的值,则最多读取 maxlen 个字符,并返回读取内容组成的 QString 字符串。 |
void QTextStream::setFieldAlignment(FieldAlignment mode) | 设置对齐方式,通常与 setFieldWidth() 一起使用。 |
void QTextStream::setFieldWidth(int width) | 设置每份数据占用的位置宽度为 width。 |
2.2 QTextStream格式描述符、描述符方法
枚举值 | 函数 | 描述 |
---|---|---|
Qt::hex | QTextStream::setIntegerBase(16) | 将指定整数对应的 16 进制数写入到文件中。 |
Qt::showbase | QTextStream::setNumberFlags(numberFlags() | ShowBase) 对于非十进制数,写入到文件中时带上相应的前缀。二进制数前缀是 0b,八进制数前缀是 0,十六进制数前缀是 0x。 |
Qt::forcesign | QTextStream::setNumberFlags(numberFlags() | ForceSign) 将数字写入文件时,带上正负号。 |
Qt::fixed | QTextStream::setRealNumberNotation(FixedNotation) | 将浮点数以普通小数的形式写入文件。 |
Qt::scientific | QTextStream::setRealNumberNotation(ScientificNotation) | 将浮点数以科学计数法的形式写入文件。 |
Qt::left | QTextStream::setFieldAlignment(AlignLeft) | 左对齐 |
Qt::right | QTextStream::setFieldAlignment(AlignRight) | 右对齐 |
Qt::center | QTextStream::setFieldAlignment(AlignCenter) | 居中对齐 |
2.3 QDataStream成员函数
函数 | 描述 |
---|---|
bool QDataStream::atEnd() const | 判断是否读到文件末尾,如果已经达到末尾,返回 true,否则返回 false |
QDataStream &QDataStream::readBytes(char *&s, uint &l) | 对于用 writeBytes() 方法写入文件的 l 和 s,只能使用 readBytes() 方法读取出来 |
int QDataStream::readRawData(char *s, int len) | 从文件中读取最多 len 字节的数据到 s 中,返回值表示实际读取的字节数。注意,调用该方法之前,需要先给 s 参数分配好内存空间 |
void QDataStream::setVersion(int v) | 不同版本的 Qt 中,同名称的数据类型也可能存在差异,通过调用此方法手动指定版本号,可以确保读取数据的一致性 |
int QDataStream::skipRawData(int len) | 跳过文件中的 len 个字节,返回实际跳过的字节数 |
QDataStream &QDataStream::writeBytes(const char *s, uint len) | 将长度 len 和 s 一起写入到文件中,对于 writeBytes() 写入的数据,只能用 readBytes() 方法读取 |
int QDataStream::writeRawData(const char *s, int len) | 将 s 中前 len 字节的数据写入文件,返回值表示成功写入的字节数 |
2.4 创建QTextStream对象并关联输入/输出设备(如文件、标准输入/输出流等)
// 1. 关联标准输入设备(stdin)
QTextStream in(stdin);
// 2. 关联标准输出设备(stdout)
QTextStream out(stdout);
// 3. 关联文件读取设备
QFile file("input.txt");
if (file.open(QIODevice::ReadOnly)) {
QTextStream in(&file);
}
// 4. 关联文件写入设备
QFile file("output.txt");
if (file.open(QIODevice::WriteOnly)) {
QTextStream out(&file);
}
// 5. 关联字节数组设备
QByteArray byteArray;
QTextStream stream(&byteArray);
// 6. 关联字符串设备
QString string;
QTextStream stream(&string);
2.5 读取和写入字符串
QString str = "Hello, World!";
// 写入字符串到QTextStream
QTextStream out(stdout);
out << str << endl;
// 读取字符串从QTextStream
QTextStream in("Hello, World!");
QString readStr;
in >> readStr;
qDebug() << "Read string: " << readStr;
运行结果
Hello, World!
Read string: "Hello,"
注意:
QTextStream在读取字符串时,默认情况下会根据空格或换行符作为分隔符。因此,在上述示例中,只读取了"Hello,“而不是整个字符串"Hello, World!”。要读取整个字符串,请使用QString的全读取函数:readAll()。
三、QTextStream的输入操作
3.1 从文件读取数据
QFile file("example.txt");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
QString line;
while (!in.atEnd()) {
line = in.readLine();
// 处理每一行数据
qDebug() << line;
}
file.close();
} else {
qDebug() << "Failed to open file.";
}
3.2 从字符串读取数据
QString str = "Hello, World!";
QTextStream in(&str);
QString word;
while (!in.atEnd()) {
in >> word;
// 处理每一个单词
qDebug() << word;
}
3.3 从标准输入读取数据
QTextStream in(stdin);
QString word;
while (!in.atEnd()) {
in >> word;
// 处理每一个单词
qDebug() << word;
}
四、QTextStream的输出操作
4.1 向文件写入数据
QFile file("data.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out << "Hello, World!" << endl;
out << "This is a sample text." << endl;
// 写入其他数据
file.close();
}
4.2 向字符串写入数据
QString data; // 声明一个空字符串
QTextStream stream(&data); // 创建一个QTextStream对象,并将其与字符串关联起来
stream << "Hello, World!" << endl; // 向字符串中写入数据
stream << "This is a sample text." << endl;
// 输出字符串中的数据
qDebug() << data; // 或者使用cout打印到控制台
4.3 向标准输出写入数据
QTextStream out(stdout); // 创建一个QTextStream对象,将其与标准输出关联
out << "Hello, World!" << endl; // 使用<<运算符将数据写入QTextStream对象
五、QTextStream的输入输出格式设置
5.1 设置数值的精度
QTextStream out(stdout);
out.setRealNumberPrecision(2);
double num = 3.14159;
out << "Number: " << num << endl; // 输出 Number: 3.14
5.2 设置字段宽度
QTextStream out(stdout);
out.setFieldWidth(8);
int num = 42;
out << "Number: " << num << endl; // 输出 Number: 42
5.3 设置填充字符
QTextStream out(stdout);
out.setFieldWidth(8);
out.setPadChar('*');
int num = 42;
out << "Number: " << num << endl; // 输出 Number: *****42
5.4 设置文本对齐方式
QTextStream out(stdout);
out.setFieldAlignment(QTextStream::AlignRight);
int num = 42;
out << "Number: " << num << endl; // 输出 Number: 42
5.5 设置字符串宽度
QTextStream out(stdout);
out.setString(&str); // str 是一个QString对象
out.setFieldWidth(8);
out << "Text: " << "hello" << endl; // 输出 Text: hello
六、QTextStream的更高级用法
6.1 设置流的编码格式
在使用QTextStream对象时,可以通过setCodec()函数设置流的编码格式。下面是一些示例:
设置输出流的编码格式为UTF-8:
QFile file("output.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out.setCodec("UTF-8");
out << "中文" << endl; // 输出中文到文件中
file.close();
}
设置输入流的编码格式为GBK:
QFile file("input.txt");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
in.setCodec("GBK");
QString str = in.readAll(); // 读取文件的内容
file.close();
}
在设置编码格式时,可以使用Qt支持的任何编码格式,例如"UTF-8"、“GBK”、"ISO-8859-1"等。如果不设置编码格式,默认情况下Qt会使用系统的默认编码格式。
注意:
设置编码格式仅适用于文本流的读取和写入操作,对于二进制数据的读取和写入无效。对于二进制数据的读取和写入操作,应该使用QDataStream对象。
6.2 QIODevice的数据流与QTextStream的关系
QIODevice是Qt中用于读写数据的设备的基类,它提供了一种通用的接口,可以用于访问各种不同类型的设备,如文件、网络套接字等。QIODevice可以用于读取和写入原始数据,但对于文本数据的读写,可以使用QTextStream类。
QTextStream是对QIODevice进行了封装的类,它提供了一种方便的方式来读写文本数据。通过QTextStream,可以以文本方式读取和写入QIODevice对象中的数据。QTextStream提供了方便的函数和操作符重载,用于读写各种数据类型,如QString、QChar、int等。
使用QTextStream可以对QIODevice进行文本读写操作,但需要注意的是,如果对QIODevice进行了原始二进制数据的读写操作,那么QTextStream可能会导致数据的丢失或损坏。因此,在读写二进制数据时,应该使用QDataStream类进行操作。
总结起来,QIODevice是Qt中用于读写数据的设备的基类,而QTextStream是对QIODevice进行了文本读写操作的封装类。在处理文本数据时,可以使用QTextStream来简化操作;在处理二进制数据时,应该使用QDataStream来确保数据的完整性。
七、QTextStream的错误处理
7.1 如何使用QTextStream类处理文本输入输出时可能出现的错误
以下是一些常见的错误类型及其解决方法:
打开文件错误: 在使用QTextStream读取或写入文件时,可能会遇到无法打开文件的情况。这可能是因为文件不存在、无权限或者文件路径错误。在打开文件之前,应该确保文件存在,并且具有适当的权限。可以使用QFile的exists()函数检查文件是否存在,并使用QFile的error()函数获取错误信息。
读取或写入格式错误: 在使用QTextStream读取或写入数据时,可能会遇到格式不匹配或解析错误的情况。这可能是因为读取或写入操作与文件内容的格式不一致。在读取数据时,可以使用QTextStream的atEnd()函数检查是否已经读取完整个文件。在写入数据时,可以使用QTextStream的status()函数检查写入的状态。
编码问题: 在读取或写入文本时,可能会遇到编码不匹配的问题。这可能导致文本的乱码或无法正确解析。在使用QTextStream读取或写入数据时,应该确保使用与文件或流相同的编码。可以使用QTextStream的setCodec()函数设置编码。另外,可以使用QTextCodec类来进行编码转换。
** 写入缓冲问题:** 在使用QTextStream写入数据时,可能会遇到缓冲区问题。QTextStream使用缓冲区来提高性能,但在某些情况下,可能需要手动刷新缓冲区。可以使用QTextStream的flush()函数手动刷新缓冲区,以确保数据被写入文件。
异常处理: 在使用QTextStream进行文本输入输出时,还应该考虑到可能发生的异常情况。可以使用try-catch语句块来捕捉并处理可能发生的异常,以确保程序能够正确处理错误。
7.2 QTextStream类提供的错误处理函数和错误状态。
函数 | 描述 |
---|---|
QTextStream::status() | 该函数返回当前文本流的状态,以QTextStream::Status枚举值表示。常见的状态值包括Ok(无错误)、ReadPastEnd(读取到文件末尾)、ReadCorruptData(读取到损坏的数据)等。可以通过此函数获取当前文本流的状态。 |
QTextStream::setCodec(const QTextCodec *codec) | 该函数设置文本流的编码方式。错误的编码方式可能导致读取或写入操作失败,无法解析或显示正确的文本。通过设置正确的编码方式,可以避免编码错误导致的异常。 |
QTextStream::setErrorString(const QString &errorString) | 该函数用于设置错误信息字符串,以便在出现错误时使用。通过setErrorString()函数设置错误信息,可以在发生错误时获取详细的错误描述。 |
QTextStream::readLine() | 该函数用于按行读取文本。如果读取到文件末尾或发生错误,函数将返回一个空的QString。 |
QTextStream::atEnd() | 该函数用于检查是否已经读取到文本流的末尾。如果已经读取完全部的数据,函数将返回true;否则返回false。 |
QTextStream::flush() | 该函数用于刷新文本流的缓冲区,确保数据被写入文件。在写入大量数据时,为了提高性能,QTextStream会将数据存储在内部的缓冲区中。通过调用flush()函数,可以强制将缓冲区中的数据写入到文件中。。 |
八、实例演示
示例1:
QTextStream out(stdout);
// out.setFieldWidth(15);
out.setPadChar('%');
out << "Hello World!\n";
out.setFieldAlignment(QTextStream::AlignLeft);
out << "Hello World!\n";
out << "Hello World!\n";
out << QString("中文\n");
out.setCodec("GBK"); //影响全局输出
out << QString::fromLocal8Bit("中文\n");
运行结果:
总结
QTextStream的主要特点如下:
支持不同的数据源: QTextStream可以读取和写入不同的数据源,包括文件、字符串和标准输入输出设备等。
支持不同的文本编码: QTextStream可以根据需要使用不同的文本编码,包括ASCII、UTF-8和UTF-16等。
容易使用: QTextStream提供了一系列的操作符重载,使得读写操作更加方便。例如,可以使用“<<”操作符将数据写入到文本流中,使用“>>”操作符从文本流中读取数据。
自动管理文本编码和格式: QTextStream会自动处理不同的文本编码和格式。例如,当写入文本数据时,它会根据文本编码自动进行转换;当读取文本数据时,它会自动跳过空格和换行符等。
支持流定向: 可以通过设置设备为只读或只写模式来限制读写操作。此外,还可以设置设备的偏移量,以便在读写操作中定位到特定的位置。
QTextStream的主要用法如下:
创建QTextStream对象: 可以通过传入一个设备对象(如QFile或QIODevice)来创建一个QTextStream对象。
读取数据: 可以使用“>>”操作符来从文本流中读取数据。例如,可以使用“stream >> data;”将数据从文本流中读取到变量data中。
写入数据: 可以使用“<<”操作符将数据写入到文本流中。例如,可以使用“stream << data;”将变量data中的数据写入到文本流中。
设置文本编码和格式: 可以使用setCodec()方法设置文本编码,使用setFieldWidth()和setPadChar()方法设置文本字段宽度和填充字符等。
定位和偏移: 可以使用seek()方法在读写操作中定位到特定的位置,使用pos()方法获取当前的偏移量。
错误处理: 可以使用status()方法检查读写操作的状态,使用setErrorString()方法设置错误信息。