QT<九> 文件系统

文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。Qt 通过QIODevice提供了对 I/O 设备的抽象,这些设备具有读写字节块的能力。下面是 I/O 设备的类图(Qt5):
在这里插入图片描述

  • QIODevice:所有 I/O 设备类的父类,提供了字节块读写的通用操作以及基本接口;
  • QFileDevice:Qt5新增加的类,提供了有关文件操作的通用实现。
  • QFlie:访问本地文件或者嵌入资源;
  • QTemporaryFile:创建和访问本地文件系统的临时文件;
  • QBuffer:读写QbyteArray, 内存文件;
  • QProcess:运行外部程序,处理进程间通讯;
  • QAbstractSocket:所有套接字类的父类;
  • QTcpSocket:TCP协议网络数据传输;
  • QUdpSocket:传输 UDP 报文;
  • QSslSocket:使用 SSL/TLS 传输数据;

文件系统分类:

  • 顺序访问设备:
    是指它们的数据只能访问一遍:从头走到尾,从第一个字节开始访问,直到最后一个字节,中途不能返回去读取上一个字节,这其中,QProcess、QTcpSocket、QUdpSoctet和QSslSocket是顺序访问设备。
  • 随机访问设备:
    可以访问任意位置任意次数,还可以使用QIODevice::seek()函数来重新定位文件访问位置指针,QFile、QTemporaryFile和QBuffer是随机访问设备,

一、基本文件操作

QFile提供了从文件中读取和写入数据的能力。通常会将文件路径作为参数传给QFile的构造函数。也可以在创建好对象最后,使用setFileName()来修改。

1、读取文件:

1) 用open(打开方式) 打开指定路径的文件。QIODevice::readOnly为只读。
2) 使用readAll()全部读取文件内容 ,按行读用readLine() ,可以使atend()判断是否读到文件尾。
3) Qt默认支持编码格式 utf-8,对于其他格式的文件需要做格式转换。
4) 利用编码格式类QTextCodeC 指定格式,

QTextCodec * codec = QTextCodec::codecForName("gbk");
ui->textEdit->setText( codec->toUnicode(array)  );

5)使用完毕要将文件对象关闭 close()

具体如下:

//点击选取文件按钮 弹出文件对话框
connect(ui->pushButton,&QPushButton::clicked,[=](){
    //打开文件
    QString path = QFileDialog::getOpenFileName(this,"Open File","D:/");
    //将路径放入文本框中
    ui->lineEdit->setText(path);

    //读取内容 放入到textEdit中
    //Qt默认读取格式是UTF-8
    QFile file(path);
    //设置打开方式
    if(!file.open(QIODevice::ReadOnly))
        return -1;

    //读取全部文件内容
   // QByteArray array = file.readAll();

    //按行读取
    QByteArray array;
    while(!file.atEnd())//没到文件末尾
        array += file.readLine();//每行

    //将读到的输入 放入textEdit
    ui->textEdit->setText(array);

//        //编码格式类
//        QTextCodec *codec = QTextCodec::codecForName("gbk");
//        //转换编码打开
//        ui->textEdit->setText(codec->toUnicode(array));

    file.close();//关闭文件

在这里插入图片描述
2、写文件:
打开文件方式QIODevice::writeOnly(清空原始内容重写)或者QIODevice::Append(追加写)。


        //进行写文件
        if(!file.open(QIODevice::Append))//用追加方式写
            return -1;
        file.write("aaaaa");
        file.close();

3、获取文件信息:

可以使用QFileInfo获取有关该文件的信息。
QFileInfo有很多类型的函数,举一些例子。比如:

  • isDir()检查该文件是否是目录;
  • isExecutable() 检查该文件是否是可执行文件等。
  • baseName() 可以直接获得文件名;
  • completeBaseName() 获取完整的文件名
  • suffix() 则直接获取文件后缀名。
  • completeSuffix() 获取完整的文件后缀
//QFileInfo文件信息
QFileInfo Info(path);
qDebug()<<"size:"<<Info.size()<<" suffix:"<<Info.suffix()
       <<" name:"<<Info.fileName()<<" path:"<<Info.filePath();
qDebug()<<"creat time:"<<Info.birthTime().toString("yyyy/MM/dd hh:mm:ss");
qDebug()<<"last modify time:"<<Info.lastModified().toString("yyyy/MM/dd hh:mm:ss");

在这里插入图片描述

二、二进制文件读写

QDataStream提供了基于QIODevice的二进制数据的序列化。数据流是一种二进制流,这种流完全不依赖于底层操作系统、CPU 或者字节顺序(大端或小端)。

由于数据流就是二进制流,因此可以直接读写没有编码的二进制数据,例如图像、视频、音频等。

QDataStream既能够存取 C++ 基本类型,如 int、char、short 等,也可以存取复杂的数据类型,例如自定义的类。实际上,QDataStream对于类的存储,是将复杂的类分割为很多基本单元实现的。

QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << QString("the answer is");
out << (qint32)42;
file.close(); // 如果不想关闭文件,可以使用 file.flush();
  • 首先打开一个名为 file.dat 的文件。然后,将刚刚创建的file对象的指针传递给一个QDataStream实例out。类似于std::cout标准输出流。后面的代码将“the answer is”和数字 42 输出到数据流。由于我们的 out 对象建立在file之上,因此相当于将问题和答案写入file。
  • 最好使用 Qt 整型来进行读写,比如qint32。这保证了在任意平台和任意编译器都能够有相同的行为。
  • 为性能起见,数据只有在文件关闭时才会真正写入。

将存储到文件中的答案取出来:

QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QString str;
qint32 a;
in >> str >> a;
file.close(); 

必须按照写入的顺序,将数据读取出来。顺序颠倒的话,程序行为是不确定的,严重时会直接造成程序崩溃。

QDataStream提供流的形式,性能上一般比直接调用原始 API 更好一些。

三、文本文件读写

QTextStream和QDataStream的使用类似,只不过它是操作纯文本文件的。

QTextStream会自动将 Unicode 编码同操作系统的编码进行转换,这一操作对开发人员是透明的。它也会将换行符进行转换,同样不需要自己处理。

QTextStream使用 16 位的QChar作为基础的数据存储单位,同样,它也支持 C++ 标准类型,如 int 等。实际上,这是将这种标准类型与字符串进行了相互转换。

QFile data("file.txt");
if (data.open(QFile::WriteOnly | QIODevice::Truncate)) 
{
    QTextStream out(&data);
    out << "The answer is " << 42;
}
data.close();

打开方式的区别:

  • QIODevice::NotOpen 未打开
  • QIODevice::ReadOnly 以只读方式打开
  • QIODevice::WriteOnly 以只写方式打开
  • QIODevice::ReadWrite 以读写方式打开
  • QIODevice::Append 以追加的方式打开,新增加的内容将被追加到文件末尾
  • QIODevice::Truncate 以重写的方式打开,在写入新的数据时会将原有数据全部清除,游标设置在文件开头。
  • QIODevice::Text 在读取时,将行结束符转换成 \n;在写入时,将行结束符转换成本地格式,例如 Win32 平台上是 \r\n
  • QIODevice::Unbuffered 忽略缓存

QTextStream的写入内容与QDataStream一致,但是读取时却会有些困难:

QFile data("file.txt");
if (data.open(QFile::ReadOnly)) 
{
    QTextStream in(&data);
    QString str;
    int ans = 0;
    in >> str >> ans;
}
data.close();

使用了QTextStream时却有所不同:读出的时候,str 里面将是 The answer is 42,ans 是 0。这是因为当使用QDataStream写入的时候,实际上会在要写入的内容前面,额外添加一个这段内容的长度值。而以文本形式写入数据,是没有数据之间的分隔的。

因此,使用文本文件时,很少会将其分割开来读取,而是使用诸如使用:

  • QTextStream::readLine() 读取一行
  • QTextStream::readAll()读取所有文本

这种函数之后再对获得的QString对象进行处理。
默认情况下,QTextStream的编码格式是 Unicode,如果我们需要使用另外的编码,可以使用:

stream.setCodec("UTF-8");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值