Qt文件系统

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是随机访问设备,

1. 基本文件操作

文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。在所有的 I/O 设备中,文件 I/O 是最重要的部分之一。因为我们大多数的程序依旧需要首先访问本地文件(当然,在云计算大行其道的将来,这一观点可能改变)。QFile提供了从文件中读取和写入数据的能力

我们通常会将文件路径作为参数传给QFile的构造函数。不过也可以在创建好对象最后,使用setFileName()来修改。QFile需要使用 / 作为文件分隔符,不过,它会自动将其转换成操作系统所需要的形式。例如 C:/windows 这样的路径在 Windows 平台下同样是可以的。

QFile主要提供了有关文件的各种操作,比如打开文件、关闭文件、刷新文件等,注意默认只识别utf8。我们可以使用QDataStream或QTextStream类来读写文件,也可以使用QIODevice类提供的read()、readLine()、readAll()以及write()这样的函数。值得注意的是,有关文件本身的信息,比如文件名、文件所在目录的名字等,则是通过QFileInfo获取,而不是自己分析文件路径字符串。

//读文件
void Widget::on_buttonRead_clicked()
{
	//设定文件对话框,并获取文件路径及文件名
    QString path = QFileDialog::getOpenFileName(this,"open","../");
    if(path.isEmpty() == false)
    {
    	//关联file对象和文件
        QFile file(path);
        //以只读的方式打开文件
        bool ret = file.open(QIODevice::ReadOnly);
        if(ret == true)
        {
#if 0
			//一次全部读取
            QByteArray arr = file.readAll();
            //把读取的结果放到编辑器
            ui->textEdit->setText(arr);
#endif
			//定义字节数组
            QByteArray arr;
            while(file.atEnd() == false)
            {
            	//一次读取一行
                arr += file.readLine();
            }
            ui->textEdit->setText(arr);
        }

        file.close();
    }
}

//写文件操作
void Widget::on_buttonWrite_clicked()
{
	//设定保存文件的路径
    QString path = QFileDialog::getSaveFileName(this,"save","../","TXT(.*txt");


    if(path.isEmpty() == false)
    {
    	//创建文件对象
        QFile file;
        file.setFileName("text");
		//以只写的方式打开文件
        bool ret = file.open(QIODevice::WriteOnly);
        if(ret == true)
        {	
        	//获取编辑器的内容
            QString str = ui->textEdit->toPlainText();
			
			//把内容写入到文件
            //file.write(str.toUtf8());
            file.write(str.toStdString().c_str());
			
        }
        file.close();
    }
}

几种常见的转换:

			//Qstring -> QByteArray
            QString buf = "abc";
            QByteArray Qbuf = buf.toUtf8();
            
            //QByteArray -> char*
            char* chs = Qbuf.data();
            
            //char* -> QString
            QString qs = QString(chs);
            
            //QString -> char*
            chch = qs.toStdString().c_str();

2.获取文件信息

QFileInfo fileinfo(path);
        qDebug()<<"filename"<<fileinfo.fileName();
        qDebug()<<"filesufix"<<fileinfo.suffix();
        qDebug()<<"size"<<fileinfo.size();
        qDebug()<<"create time"<<fileinfo.created()
        							.toString("yyyy-MM-dd hh:mm:ss");

3.QDataStream&QTextStream

  • QDataStream提供了基于QIODevice的二进制数据的序列化
  • 数据流是一种二进制流,这种流完全不依赖于底层操作系统、CPU 或者字节顺序(大端或小端)。例如,在安装了 Windows 平台的 PC 上面写入的一个数据流,可以不经过任何处理,直接拿到运行了 Solaris 的 SPARC 机器上读取。
  • 由于数据流就是二进制流,因此我们也可以直接读写没有编码的二进制数据,例如图像、视频、音频等。
  • QDataStream既能够存取 C++ 基本类型,如 int、char、short 等,也可以存取复杂的数据类型,例如自定义的类。实际上,QDataStream对于类的存储,是将复杂的类分割为很多基本单元实现的。
  • 结合QIODevice,QDataStream可以很方便地对文件、网络套接字等进行读写操作。我们从代码开始看起:
QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << QString("the answer is");
out << (qint32)42;
  • 在这段代码中,我们首先打开一个名为 file.dat 的文件(注意,我们为简单起见,并没有检查文件打开是否成功,这在正式程序中是不允许的)。
  • 然后,我们将刚刚创建的file对象的指针传递给一个QDataStream实例out。类似于std::cout标准输出流,QDataStream也重载了输出重定向<<运算符。
  • 后面的代码就很简单了:将“the answer is”和数字 42 输出到数据流。由于我们的 out 对象建立在file之上,因此相当于将问题和答案写入file。
  • 需要指出一点:最好使用 Qt 整型来进行读写,比如程序中的qint32。这保证了在任意平台和任意编译器都能够有相同的行为。
  • 如果你直接运行这段代码,你会得到一个空白的 file.dat,并没有写入任何数据。这是因为我们的file没有正常关闭。为性能起见,数据只有在文件关闭时才会真正写入。因此,我们必须在最后添加一行代码:
file.close(); // 如果不想关闭文件,可以使用 file.flush();
接下来我们将存储到文件中的答案取出来
QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QString str;
qint32 a;
in >> str >> a;
  • 唯一需要注意的是,你必须按照写入的顺序,将数据读取出来。顺序颠倒的话,程序行为是不确定的,严重时会直接造成程序崩溃。
  • 那么,既然QIODevice提供了read()、readLine()之类的函数,为什么还要有QDataStream呢?QDataStream同QIODevice有什么区别?
  • 区别在于,QDataStream提供流的形式,性能上一般比直接调用原始 API 更好一些。我们通过下面一段代码看看什么是流的形式:
QFile file("file.dat");
file.open(QIODevice::ReadWrite);
 
QDataStream stream(&file);
QString str = "the answer is 42";

stream << str;

QTextStream:

  • 二进制文件比较小巧,却不是人可读的格式。而文本文件是一种人可读的文件。为了操作这种文件,我们需要使用QTextStream类
  • QTextStream和QDataStream的使用类似,只不过它是操作纯文本文件的。
  • QTextStream会自动将 Unicode 编码同操作系统的编码进行转换,这一操作对开发人员是透明的。它也会将换行符进行转换,同样不需要自己处理
  • QTextStream使用 16 位的QChar作为基础的数据存储单位,同样,它也支持 C++ 标准类型,如 int 等。实际上,这是将这种标准类型与字符串进行了相互转换。
void Widget::writeTextDate()
{
    QFile file;
    file.setFileName("./1.txt");

    bool ret = file.open(QIODevice::WriteOnly);
    if(ret == true)
    {
        QTextStream stream(&file);
        stream<<QString("i am text textStream");
        file.close();
    }
}

void Widget::readTextDate()
{
    QFile file;
    file.setFileName("./1.txt");
    readDate();
    bool ret = file.open(QIODevice::ReadOnly);
    if(ret == true)
    {
        QTextStream stream(&file);
        stream.setCodec("UTF-8");
        QString str;
        stream>>str;
        qDebug()<<str.toStdString().c_str();
        file.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wolf鬼刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值