QTextStream 类(文本流)和 QDataStream 类(数据流)

QTextStream 用法

QTextStream 类(文本流)和 QDataStream 类(数据流)

--------------------------------------------------------

================================

QTextStream 用法

        QTextStream 是一个用于读写文本的 Qt 类,可以从文件、字节数组、标准输入输出设备等读取和写入文本。它提供了一系列方便的方法来读取和写入文本数据,例如 readLine()、readAll()、write()、operator<< 等。

下面是 QTextStream 的一些常用方法:

1、 构造函数

QTextStream 可以通过构造函数来指定输入或输出设备,例如:

    //cpp
    QFile file("example.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;
     
    QTextStream in(&file); // 从文件读取文本

2. 读取操作

QTextStream 有许多读取操作,可以读取单个字符、单词、一行等,例如:

    //cpp
    QChar c = in.read(); // 读取单个字符
    QString word = in.readWord(); // 读取一个单词
    QString line = in.readLine(); // 读取一行文本

3. 写入操作

QTextStream 也有许多写入操作,可以写入单个字符、字符串、数值等,例如:

    //cpp
    out << "Hello, world!" << endl; // 写入字符串和换行符
    out << 42 << " is the answer." << endl; // 写入数值和字符串

4. 格式化输出

QTextStream 支持格式化输出,例如可以指定输出的精度、宽度、填充字符等,例如:

    //cpp
    out.setFieldWidth(10);
    out.setPadChar('-');
    out.setRealNumberPrecision(4);
    out << 3.14159265358979323846 << endl; // 输出:--3.1416

5. 读写位置控制

QTextStream 可以控制读写位置,可以获取当前读写位置、设置读写位置等,例如:

    //cpp
    int pos = in.pos(); // 获取当前读取位置
    in.seek(0); // 设置读取位置为文件开头

6. 字符编码设置

QTextStream 可以设置字符编码,例如:

    //cpp
    in.setCodec("UTF-8"); // 设置输入流的字符编码为 UTF-8
    out.setCodec("GBK"); // 设置输出流的字符编码为 GBK

以上是 QTextStream 的一些常用用法,更多详细信息可以参考 Qt 官方文档。
————————————————
版权声明:本文为CSDN博主「Ivy_belief」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bigger_belief/article/details/130584935

QTextStream 的简单理解

文章目录

    QTextStream 的简单理解
        QTextStream类提供了使用QIODevice读写文本的基本功能。
        还有一种通常的用法就是控制台命令的读写
        除了QTextStream的构造函数,还要常用的一些方法
        通常有三种方式来读文本文件
    Qt提供了几个和iostream相似的全局函数:

QTextStream 的简单理解

QTextStream类提供了使用QIODevice读写文本的基本功能。

QTextStream可以操作QIODevice上,支持QByteArray和QString。如果使用QTextStream的operators,可以方便的读写words,lines 和numbers. 对一般的文本,QTextStream支持格式化对齐,格式化数字 等。例如

QFile data(“output.txt”);
if (data.open(QFile::WriteOnly | QFile::Truncate)) {
QTextStream out(&data);
out << "Result: " << qSetFieldWidth(10) << left << 3.14 << 2.7;
// writes "Result: 3.14 2.7 "
}

还有一种通常的用法就是控制台命令的读写,例如:

QTextStream stream(stdin);
QString line;
while (stream.readLineInto(&line)) {

}

除了QTextStream的构造函数,还要常用的一些方法,例如:

setDevice() : 设置设备
setString(): 设置字符串
seek():查找位置
atEnd():返回是否还有数据可读
flush():清空写缓存区

QTextStream 使用的是Unicode 缓存,Qt中的QTextCodec类 可以支持各种字符集。

通常有三种方式来读文本文件:

    chunk By chunk(块读):readLine()和readAll()
    Word By Word(按字读):
    character By character(按字节读):

Qt提供了几个和iostream相似的全局函数:

  • - bin设置QTextStream来读/写二进制数字
  • - oct设置QTextStream来读/写八进制数字
  • - dec设置QTextStream来读/写十进制数字
  • - hex设置QTextStream来读/写十六进制数字
  • - endl强制换行
  • - flush强制QIODevice刷新任何被缓存的数据
  • - ws作为任何可用的控制符(在输入的时候)
  • - reset重新设置QTextStream为它的缺省模式(请见reset())
  • - qSetW(int)设置字段宽度作为指定参数
  • - qSetFill(int)设置填充字符作为指定参数
  • - qSetPrecision(int)设置精确度作为指定参数

Qt 官方手册

Detailed Description

QTextStream can operate on a QIODevice, a QByteArray or a QString. Using QTextStream's streaming operators, you can conveniently read and write words, lines and numbers. For generating text, QTextStream supports formatting options for field padding and alignment, and formatting of numbers. Example:

  QFile data("output.txt");
  if (data.open(QFile::WriteOnly | QFile::Truncate)) {
      QTextStream out(&data);
      out << "Result: " << qSetFieldWidth(10) << left << 3.14 << 2.7;
      // writes "Result: 3.14      2.7       "
  }

Related Non-Members

QTextStream &bin(QTextStream &stream)

Calls QTextStream::setIntegerBase(2) on stream and returns stream.
See also oct(), dec(), hex(), and QTextStream manipulators.

简单示例:

include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QStringList>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //写入文件
    QFile myFile("log.txt");
    if(!myFile.open(QIODevice::WriteOnly))
    {
        qDebug()<<myFile.errorString();
    }
    QTextStream textStream(&myFile);
    textStream<<"this is   first line.\r\n";
    textStream<<"this is second line.\r\n";
    textStream<<"this is third line.\r\n";
    textStream.flush();
    myFile.close();
    //读取文件
    if(!myFile.open(QIODevice::ReadOnly))
    {
        qDebug()<<myFile.errorString();
    }
    textStream.setDevice(&myFile);
 
    while(!textStream.atEnd())
    {
        QString str1 = textStream.readLine();//每次读取一行
        qDebug()<<str1;
    }
    textStream.seek(0);
    QString strAll = textStream.readAll();//全部读取
    qDebug()<<strAll;
    //每一次读取一个单词,过滤掉空格
    textStream.seek(0);
    while(!textStream.atEnd())
    {
        QString str;
        textStream>>str;
        qDebug()<<str;
    }
    //每一次读取一个字节
    textStream.seek(0);
    while(!textStream.atEnd())
    {
        textStream.skipWhiteSpace();
        QString str = textStream.read(1);
        qDebug()<<str;
    }
 
    myFile.close();
    return a.exec();
}

————————————————
版权声明:本文为CSDN博主「qq_21291397」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_21291397/article/details/107503522

QTextStream 类(文本流)和 QDataStream 类(数据流)

QTextStream 类(文本流)和 QDataStream 类(数据流)Qt 输入输出的两个核心类,其作用分别如下:

①、QTextStream 类:用于对数据进行文本格式的读/写操作,可在 QString、QIODevice或 QByteArray 上运行,比如把数据输出到 QString、QIODevice 或 QByteArray 对象上,或进行相反的操作。

②、QDataStream 类:用于对数据进行二进制格式的读/写操作,QDataStream 只可在QIODevice 或 QByteArray 上运行,因为 QString 只存放字符数据

QIODevice 类是 Qt 中所有 I/O 设备的基础接口类(这是一个抽象类),也就是说 QIODevice及其子类描述的是 I/O 设备,该类为支持读/写数据块的设备提供了通用实现和抽象接口,比如 QFile、QBuffer、QTcpSocket 等

QIODevice 把设备分为两类:随机存储设备和顺序存储设备

①、随机存储设备:可定位到任意位置(使用 seek()函数),随机存储设备有 QFile,QTemporaryFile,QBuffer

②、顺序存储设备:不支持任意的位置存储,顺序存储设备有 QProcess、QTcpSocket、QUdpSocket 和 QSslSocket

QBuffer 类为 QByteArray 提供了一个 QIODevice 接口,以允许使用 QIODevice 接口来访问 QByteArray。默认情况下,创建一个 QBuffer 时,会自动在内部创建一个 QByteArray缓冲区

 

QDataStream 类

 字节序:即多字节数据(即大于一个字节的数据)在内存中的存储顺序,有如下两种方式

Little-Endian(LE,小端):即低位字节存储在低地址端,高位字节存储在高地址端

Big-Endian(BE,大端):即高位字节存储在低地址端,低位字节储倣在高地址端。这是 QDataStream 的默认字节序。

比如对于整数 0x2345,若按 big-endian(大端)顺序存储,则按 0x23、0x45 的顺序存储,若按 little-endian(小端)顺序存储,则以 0x45、0x23 的顺序存储

QDataStream 实现了基本的 C++数据类型的序列化,比如 char,short,int,char *等。更复杂的数据类型的序列化是通过分解原始单元来完成的

QDataStream 支持的 Qt 类型有 QBrush、QColor、QDateTime、QFont、QPixmap、QString、QVariant 等类型,还包括容器类型,比如 QList、QVector、QSet、QMap 等

对于整数,建议始终转换为 Qt 整数类型(比如 qint32 等)进入写入,并将其读入为相同的Qt整数类型,这样可以确保获取确定的大小的整数,以避免编译器和平台差异的影响(注:C++语法只规定了 int,short 等类型的最小长度,未规定最大长度)
QDataStream读写文件

win.h

    #ifndef WIN_H
    #define WIN_H
     
    #include <QWidget>
    #include <QPushButton>
    #include <QFile>
    #include <QDataStream>
     
    class Win : public QWidget
    {
        Q_OBJECT
     
    public:
        Win(QWidget *parent = nullptr);
        ~Win();
     
    private:
        QPushButton *pb;
        QFile* f;
     
     
     
    };
    #endif // WIN_H

win.cpp

    #include "win.h"
     
    Win::Win(QWidget *parent)
        : QWidget(parent)
    {
        this->resize(300,200);
        pb=new QPushButton("AAA",this);
        pb->move(10,10);
     
        f=new QFile("l.txt");
        f->open(QIODevice::WriteOnly); //以只写方式打开文本l.txt
        QIcon i("l.jpg");
        QPoint p(22,22);
        QDataStream out(f); //创建QDataStream对象并与QFile对象关联
        out <<i<<QString("BBB")<<p; //把对象i,字符串 BBB 和对象p写入文件l.txt中
        //  << 输出符号
        f->close(); //关闭文件
     
        f->open(QIODevice::ReadOnly); //以只读方式重新打开文本l.txt,以读取其内容
        QIcon i1;
        QString s;
        QPoint p1;
     
        QDataStream in(f); //创建QDataStream 对象并与 QFile 对象关联
        in>>i1>>s>>p1; //把文件l.txt 的内容读出并存储到i1、s 和 p1 中
        //  >>  输入符号
        //注意,读取数据类型的顺序应与写入时的一致
        pb->setIcon(i1);  //使用从文件读取到的数据设置按钮的图标
        pb->setText(s);
        pb->move(p1);
        f->close();
     
     
    }
     
    Win::~Win()
    {
    }

读写原始二进制数据

可以使用int readRawData(char *s, int len)将数据读入一个预先分配好的char*;

缓冲区 s 必须被预先分配,缓冲区 s 使用 new[]分配,使用 delete 操作符销毁

可以使用int writeRawData(const char *s, int len)函数把原始数据写入datastream

使用这种方式的话,要由你自己进行所有数据的编码和解码

​int writeRawData(const char *s, int len);​

把 len 个字节的数据从缓冲区 s 写入流,并返回实际写入的字节数,若发生错误,则返回-1,注意:数据未编码

​int readRawData(char *s, int len);​

从流中读取最多 len 个字节到缓冲区 s 中,并返回读取的字节数,若产生错误,则返回−1,缓冲区 s 必须被预先分配。数据是未编码的。

    QFile f("l.txt");
     
    QDataStream out(&f);
     
     
    f.open(QIODevice::WriteOnly);
        out<<QString("BBB");
        /*以二进制形式写入一个字符串BBB到文件l.txt中,注意:以此种方式写入的字符串BBB是已经编了码的,
          因此实际写入文件的内容并不一定是4字节的大小。*/
        char c[4]="CCC";  //创建缓冲区
        int i1=out.writeRawData(c,4); //把缓冲区c中的4个字节内容写入流中
        //注:因为此函数写入的内容未编码,因此将直接向文件写入一个字符串"ccc"(4字节大小)
        qDebug()<<i1;
        f.close();
     
        QDataStream in(&f);
        f.open(QIODevice::ReadOnly);
        char *pc=new char[114]; //创建一个缓冲区
        int i2=in.readRawData(pc,114); //从流中读取最多114个字节内容放到缓冲区pc中
        //此时pc中保存的值就是文件l.txt中的原始二进制数据,注意:实际未必会读取114个字节
        qDebug()<<i2; //输出实际读取的字节数
        for(int j=0;j<i2;j++){    //输出全部内容,以循环的方式逐字符输出
            qDebug()<<pc[j];
        }
     
        f.close();
     
     
    }

QFile f("l.txt");

 
实例:读取保存自定义类对象

readBytes() 和 writeBytes()

writeBytes()

QDataStream &QDataStream::writeBytes(const char *s, uint len)

先写入一个quint32的数据,该值就是将要写入的数据的长度;紧接着写入相应数据

readBytes()

QDataStream &QDataStream::readBytes(char *&s, uint &l)

先读取一个quint32值,该值就是将要读取的数据的长度,然后读取相应字节的数据到预先定义好的char*中

注意,readBytes() 不需要我们事先分配好内存

仍然需要程序员自己进行编码和解码的

    QFile f("l.txt");
        f.open(QIODevice::WriteOnly);
        QDataStream out(&f);
        char c[4]="CCC";
        out.writeBytes(c,sizeof(c));  //写入char字符串
        //参数2:写入数据的字节数
        qint32 n=898989;
        QByteArray ba;
        ba.setNum(n);
        out.writeBytes(ba,ba.size());  //写入QByteArray数据
        f.close();
     
        QDataStream in(&f);
        f.open(QIODevice::ReadOnly);
        char* cc;  //不需要分配内存
        char* dd;
        QByteArray ba1;
        uint nn,mm;
        in.readBytes(cc,nn);  //读取数据
        //读取的数据保存到cc中
        //参数2:返回读取数据的字节数
        in.readBytes(dd,mm);
        qDebug()<<cc<<",   "<<nn;
        qDebug()<<dd<<",   "<<mm;
        f.close();

QTextStream 类(文本流)

字节顺序标记 BOM(Byte Order Mark):BOM 是出现在文本文件头部的一种用于标识文件格式的编码,UTF-16 和 UTF-32 通常使用 BOM 来表示文本的字节序,字节序对 UTF-8没有意义,因此 UTF-8 不需要使用 BOM 来表明字节序,但可使用 BOM 来表明其编码方式,通常使用 0xEF BB BF 来表明此文本是使用的 UTF-8 编码。UTF-8 不推荐使用无意义的 BOM,但很多程序在保存 UTF-8 编码的文件时仍然带有 BOM(即在文件的开头加上 0xEF BB BF 三个字节),比如 windows 的记事本等,因此在编辑 UTF-8 的文件时,需要注意该文件是否带有 BOM 的问题

QString 存储一个 16 位的 QChar 字符串,其中每个 QChar 对应一个 Unicode4.0 字符(即存储的字符含有16位),对于代码值超过65536的Unicode字符使用两个连续的QChar表示。QByteArray 类用于存储原始字节和传统的 8 位以'\0'终止的字符串。Qt 内部大量使用了QString,因此通常应使用 QString,QByteArrayy 主要用于存储原始二进制数据

QTextStream 类用于对数据进行文本格式的读/写操作,可在 QString、QIODevice 或QByteArray 上运行,使用 QTextStream 可方便的读/写单词、行和数字,另外 QTextStream还对字段填充、对齐和数字格式提供了格式选项的提供支持

QTextStream 在其内部使用 16 位(两字节)长的 QChar 类型存放每个字符,字符集使用Unicode,这与 C++的 iostream 不同,iostream 每个字符的类型由模板参数 charT 指定,标准库已将其特化为 char 和 wchar_t 类型,除此之外还可为 charT 指定其他类型,而QTextStream 的字符类型固定为 QChar 类型,使用此种方式简化了 Qt 流的总体结构,但也增加了字符占据的空间
写入文件

    //QTextStream 虽然能在 Unicode 编码与其他任意编码间进行转换,但并不支持其他任间编码间的转换,因
        //此在使用字符串时,建议使用 QString 类型的字符串,以确保输出的字符串为 Unicode 编码
        QFile f("l.txt");
        QTextStream out(&f);  //创建文本流对象并关联到文件
        f.open(QIODevice::WriteOnly);
        out<<QString("a23b 检说 ui9d 极")<<898989<<"\n";  //写入文本
        //  \n  换行符
        out<<"liming"<<68140318;
     
        f.close();

读文件

l.txt文件内容如下:

中国人民万岁 我爱我的祖国 我家在天津

limi ng68140318

我是一位物理教师

    QFile f("l.txt");
        QTextStream in(&f);
        f.open(QIODevice::ReadOnly);
        QChar c;
        in>>c; //从l.txt 读取一个字符
        qDebug()<<c;  //输出\u4e2d(这是“中”字的 Unicode 编码)
        //一个汉字一个字符
        bool b=in.seek(0); //把读写指针设置为0,以便从头开始读取
        //成功返回true;否则返回false
        QString s;
        in>>s; //读取一个单词到 s 中(单词由空格分开)
        qDebug()<<s; //输出"中国人民万岁"
        in>>s; //继续读取下一个单词到 s 中
        // >>运算符会自动跳过前导空格,所以读取到的单词前面没有空白符
        qDebug()<<s; //输出"我爱我的祖国"
        in.skipWhiteSpace(); //跳过空白
        //从流中读取并丢弃空白,直到检测到非空格字符,或直到atEnd()返回true。此函数在逐字符读取流时非常有用。
        //空白字符是QChar::isSpace()返回true的所有字符
        s=in.read(10); //读取10个字符,并把读取到的字符保存到s中
        //  \n 是一个字符   一个汉字一个字符
        qDebug()<<s; //输出"我家在天津\nlimi"
        s=in.readLine(); //继续读取余下的整行文本,并把结果保存到 s 中
        //注意:返回的结果中不包含行尾符\n
        qDebug()<<s; //输出"     ng68140318",注意:因为没有跳过空白,所以最前面是空白字符
        in.seek(0);
        s=in.readLine(10); //读取10个字符或整行(本行大于10个字符,因此只读取10个字符), 并把结果保存到s中
        qDebug()<<s;
        in.seek(0);
        s=in.readAll(); //读取整个文本
        qDebug()<<s;  //"中国人民万岁 我爱我的祖国        我家在天津\nlimi     ng68140318\n\n我是一位物理教师"
     
        //使用循环逐行读取整个文件
        in.seek(0);
        s="";
        while(!in.atEnd()){
            // atEnd()  是否到尾部   是返回true
            s+=in.readLine();
        }
        qDebug()<<s; //"中国人民万岁 我爱我的祖国        我家在天津limi     ng68140318我是一位物理教师"
     
     
        f.close();

其它指令

    QFile f("l.txt");
        f.open(QIODevice::ReadOnly);
        QTextStream in(&f);
     
        QTextCodec *tp=in.codec();  //返回当前流的编解码器
        QIODevice *d=in.device();  //返回当前的设备
        //与 &f  相同
        in.setCodec("UTF-8");  //设置编码
     
        QString s;
        qint64 n;
        s=in.read(9);
        n=in.pos();  //返回当前流读写指针的位置
        QChar qc=in.padChar();//返回当前填充字符
        //' '
        //in.setPadChar()  设置当前填充字符

————————————————
版权声明:本文为CSDN博主「十年编程老舅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_73443478/article/details/129443418

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值