c++ Qt5学习笔记 2021-1-21(文件系统QFile、QFileInfo、QDir、QFileSystemWatcher等使用,读取文本显示乱码,QDataStream二进制字节流读写)

44 篇文章 8 订阅

文件目录操作相关类:

QFile:除了打开文件操作外,QFile还有复制文件、删除文件等功能。
QCoreApplication:用于提取应用程序路径、程序名等文件信息。
QFileInfo:用于提取文件的信息,包括路径、文件名、后缀等。
QDir:用于提取目录或文件信息,获取一个目录下的文件或目录列表,创建或删除目录和文件,文件重命名等操作。
QTemporaryDirQTemporaryFile:用于创建临时目录和临时文件。
QFileSystemWatcher:文件和目录监听类,监听目录下文件的添加、删除等变化,监听文件修改变化。

1、QFile 类与文本读写:

(1)相关函数:
QFile::QFile()         //构造一个QFile对象
QFile::copy()      //复制文件
QFile::atEnd()         //virtual  如果在文件末尾返回true,否则false
QFile::close()         //virtual  关闭一个打开的QFile
QFile::encodeName()   //static  转换名字为本地编码
QFile::decodeName()   //static   转换名字为本地编码
QFile::exists()       //static  判断给定函数是否存在,存在True,不存在False
QFile::flush()        //virtual  将存放在缓冲区中的文件刷新输出到磁盘上
QFile::getch()        //virtual   从一个文件中读取一个字节/字符
QFile::handle()       //返回文件的句柄
QFile::fileName()     //返回被文件的名字
QFile::rename()       //重命名文件
QFile::open()         //打开一个文件
QFile::putch()        //virtual   向文件中写入
QFile::readAll()      //virtual    返回所有数据
QFile::readLine()     //读取文件中的(一)行数据
QFile::remove()       //删除QFile对象的文件
QFile::setDecodingFunction()      //static    设置8位文件名的译码函数位f
QFile::setEncodingFunction()     //static    设置Unicode文件名的编码函数为f
QFile::size()         //返回文件的大小
QFile::ungetch()         //输出字符返回到文件中
QFile::setPermissions()          //设置权限,枚举类型:QFileDevice::Permission

其中,QFile::open()函数的参数QIODevice::OpenModelFlag枚举类型参数,有如下几种方法:

QIODevice::ReadOnly   //以只读方式打开文件,用于载入文件
QIODevice::WriteOnly   //以只写方式打开文件,用于保存文件。隐含Truncate,会把原来的内容删除
QIODevice::ReadWrite   //以读写方式打开
QIODevice::Append    //以添加模式打开,新写入文件的数据添加到文件尾部
QIODevice::Truncate    //以截取方式打开文件,文件原有的内容全部被删除
QIODevice::Text      //以文本方式打开文件,读取时'\n'被自动翻译为换行符,写入时字符串结束符会自动翻译为系统平台的编码,如windows平台下是'\r\n'
(2)读文本:

QFile读取中文文本时乱码:

使用QTextCodec设置显示格式为GBK

QTextCodec *textcodec1  = QTextCodec::codecForName("GBK");
QString txt1 = textcodec1  ->toUnicode(aFile.readAll());

简单的使用:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->pushButton->setText(u8"选择文件");
}

void MainWindow::on_pushButton_clicked()   //按钮
{
    QString curPath = QDir::currentPath();  //当前项目所在位置
    QString title = u8"打开一个文件";
    QString filter = u8"文本文件(*.txt);;程序文件(*.h *.cpp);;所有文件(*.*)";
    QString aFileName = QFileDialog::getOpenFileName(this,title,curPath,filter);   //选择文件
    if(aFileName.isEmpty())  //路径为空
        return;
    QFile aFile(aFileName);   //转为QFile类型
    if (!aFile.exists())  //不存在
        return;
    if (!aFile.open(QIODevice::ReadOnly|QIODevice::Text))  //以只读和文本方式打开文件
        return;

    QTextCodec *textcodec1 = QTextCodec::codecForName("GBK");    //转GBK显示格式
    QString txt1 = textcodec1->toUnicode(aFile.readAll());
    ui->label->setText(txt1);
    aFile.close();
}

MainWindow::~MainWindow()
{
    delete ui;
}

运行结果:
在这里插入图片描述

(3)写文本:

使用write()可以对文本进行覆盖重写,修改按钮代码:
(注:以下代码写文本会把txt原本内容覆盖,不想覆盖,而是在末尾添加就把打开方式改为Append

void MainWindow::on_pushButton_clicked()
{
    QString curPath = QDir::currentPath();  //当前项目所在位置

    QString title = u8"打开一个文件";
    QString filter = u8"文本文件(*.txt);;程序文件(*.h *.cpp);;所有文件(*.*)";
    QString aFileName = QFileDialog::getOpenFileName(this,title,curPath,filter);   //选择文件

    if(aFileName.isEmpty())
        return;
    QFile aFile(aFileName);   //转为QFile类型
    if (!aFile.exists())  //不存在
        return;
    if (!aFile.open(QIODevice::WriteOnly|QIODevice::Text))  
    //改为仅能写入打开,会把原文内容覆盖。不想覆盖就把writeOnly改为Append
        return;

    QString str = u8"撒大苏打";
    QByteArray strBytes = str.toUtf8();
    aFile.write(strBytes,strBytes.length());   //写入
    aFile.close();
}

运行程序:
选择文本文件,然后打开文本文件查看:
在这里插入图片描述
原本内容已被覆盖。

(4)QFile和QTextStream的读写文本文件:

QTextStream结合QFile使用文本数据流读取文件,使用如下:

void MainWindow::on_pushButton_clicked()   //按钮
{
    QString curPath = QDir::currentPath();  //当前项目所在位置

    QString title = u8"打开一个文件";
    QString filter = u8"文本文件(*.txt);;程序文件(*.h *.cpp);;所有文件(*.*)";
    QString aFileName = QFileDialog::getOpenFileName(this,title,curPath,filter);   //选择文件

    if(aFileName.isEmpty())
        return;
    QFile aFile(aFileName);   //转为QFile类型
    if (!aFile.exists())  //不存在
        return;
    if (!aFile.open(QIODevice::ReadOnly|QIODevice::Text))  //仅读取
        return;

    QTextStream textstream(&aFile);    //数据流读取文件
    textstream.setAutoDetectUnicode(true);  //自动检测Unicode,才能显示汉字
    ui->label->setText(textstream.readAll());

    aFile.close();
}

数据流写入文件,修改一下按钮的功能:(同样的是否覆盖原本的内容,还是取决于读取文件的方式,不想覆盖就使用append方式打开)

void MainWindow::on_pushButton_clicked()
{
    QString curPath = QDir::currentPath();  //当前项目所在位置

    QString title = u8"打开一个文件";
    QString filter = u8"文本文件(*.txt);;程序文件(*.h *.cpp);;所有文件(*.*)";
    QString aFileName = QFileDialog::getOpenFileName(this,title,curPath,filter);   //选择文件

    if(aFileName.isEmpty())
        return;
    QFile aFile(aFileName);   //转为QFile类型
    if (!aFile.exists())  //不存在
        return;
    if (!aFile.open(QIODevice::Append|QIODevice::Text))  //仅写入打开
        return;

    QTextStream textstream(&aFile);    //用文本读取文件
    textstream.setAutoDetectUnicode(true);  //自动检测Unicode,才能显示汉字
    QString str = u8"啊的卡上";

    textstream<<str;   //写入数据流
    aFile.close();
}

2、QCoreApplication类:

QCoreApplication是所有应用程序类的基类,由于界面类只是它的一个派生类,除了具有界面类的所有功能,QCoreApplication也提供了一些有关文件系统的静态函数:

QString applicationDirPath()               //返回应用程序启动路径
QString applicationFilePath()             //返回应用程序的带有目录的完整文件名
QString applicationName()                 //返回应用程序名称,无路径,无后缀
QStringList  libraryPaths()               //返回动态加载库文件时,应用程序搜索的目录列表
void setOrganizationName(QString &orgName)   //为应用程序设置一个机构名
QString organizationName()               //返回应用程序机构名
void exit()                              //退出应用程序

3、QFileInfo类:

QFileInfo类提供的文件系统的接口函数用于查看文件信息,可以创建QFileInfo对象来指定某一文件作为当前文件:

QFileInfo file_info("E:/1.txt")

也可以使用setFile()来指定一个文件作为当前文件:

QFileInfo file_info;
file_info.setFile("E:/1.txt");

相关函数:

void setFile(QString &file)           //设置一个文件名,作为QFileInfo操作的文件
QString absoluteFilePath()            //返回带有文件名的绝对文件路径
QString absolutePath()                //返回绝对路径,不带文件名
QString fileName()                    //返回去除路径的文件名
QString filePath()                    //返回包含路径的文件名
QString path()                        //返回不含文件名的路径
qint64 size()                         //返回文件大小
QString baseName()                    //返回文件基名,第一个"."之前的文件名(有些文件名中有多个".")
QString completeBaseName()            //返回文件基名,最后一个"."之前的文件名(有些文件名中有多个".")
QString suffix()                      //最后一个"."之后的后缀
QString completeSuffix()              //第一个"."之后的后缀
bool isDir()                      //判断当前对象是否是一个目录或目录的快捷方式
bool isFile()                     //判断当前对象是否是一个文件或文件的快捷方式
bool isExecutable()               //判断当前文件是否是可执行文件
QDateTime created()               //返回文件创建时间
QDateTime lastModified()           //返回文件最后一次被修改的时间
QDateTime lastRead()               //返回文件最后一次被读取的时间
bool exists()                     //判断文件是否存在
bool exists(QString &file)          //静态函数,判断file表示的文件是否存在

使用时:

void MainWindow::on_pushButton_2_clicked()   //按钮点击
{
    QFileInfo file_Info("E:/2.jpg");
    QString ab_files_path = file_Info.absoluteFilePath();  //绝对路径
    qint64 size = file_Info.size();     //文件大小
    QDateTime created_time = file_Info.created();      //创建时间
    QDateTime modify_time = file_Info.lastModified();   //最后一次修改时间
    QDateTime lastRead_time = file_Info.lastRead();    //最后一次读取
    
    qDebug()<<u8"文件绝对路径:"<<ab_files_path<<'\n'
           <<u8"文件大小:"<<size<<'\n'
          <<u8"创建时间:"<<created_time<<'\n'
         <<u8"最后一次修改时间:"<<modify_time<<'\n'
        <<u8"最后一次读取时间"<<lastRead_time;
}

运行结果:
在这里插入图片描述

4、QDir类:

QDir是目录操作的类,QDir的一些静态变量有:

//函数原型                              功能
QString   tempPath()                   //返回临时文件目录名称
QString   rootPath()                   //返回根目录名称
QString   homePath()                   //返回主目录名称
QString   currentPath()                //返回当前目录名称
bool   setCurrent(QString &path)       //设置path表示的目录为当前目录
QFileInfoList drives()                 //返回系统的根目录列表,在windows系统上返回的是盘符列表

相关成员函数有:

//函数原型                                             //功能
QString absoluteFilePath(QString &fileName)        //返回当前目录下的一个文件的含绝对路径文件名
QString absolutePath()                             //返回当前目录的绝对路径
QString canonicalPath()                            //返回当前目录的标准路径
QString filePath(QString &fileName)                //返回目录下一个文件的目录名
QString dirName()                                  //返回最后一级目录的名称
bool exists()                                      //判断当前目录是否存在
QStringList entryList(Filters filters=NoFilter,SortFlags sort=NoSort)  //返回目录下所有文件名、子目录名等
bool mkdir(QString &dirName)                       //在当前目录下建一个名称为dirName的子目录
bool rmdir(QString &dirName)                       //删除指定的目录 dirName
bool remove(QString &fileName)                     //删除当前目录下的文件 fileName
bool rename(QString &oldName,QString &newName)     //将文件或目录oldName更名为newName
void setPath(QString &path)                        //设置QDir对象的当前目录
bool removeRecursively()                          //删除当前目录及其下面的所有文件

返回目录下文件名、子目录的entryList()函数,需要传递枚举类型参数QDir::Filter,常用枚举类型参数有:

QDir::ALLDirs   //列出所有目录名
QDir::Files    //列出所有文件
QDir::Drives    //列出所有盘符
QDir::NoDotAndDotDot    //不列出特殊的符号,如"."和".."
QDir::AllEntries          //列出目录下所有项目

使用时:

void MainWindow::on_pushButton_clicked()
{
    QDir dir("E:/");
    //获取目录下所有文件名、子目录等
    QStringList strlist = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);   
    for(int i=0;i<strlist.count();i++)
    {
        qDebug()<<u8"第"<<i+1<<u8"个文件为:"<<strlist.at(i);
    }
}

运行结果:
在这里插入图片描述

QTemporaryDirQTemporaryFile

QTemporaryDir用于创建、删除临时目录的类,它的一些成员函数:

//函数原型                              功能
void setAutoRemove(bool b)             //设置为是否自动删除
QString path()                         //返回创建的临时目录名称
bool remove()                          //删除此林师目录及其下面所有文件

5、QFileSystemWatcher类:

QFileSystemWatcher是对目录和文件进行监听的类,把某些目录或文件添加到QFileSystemWatcher对象的监听列表后,当目录下发生文件新建、删除等操作时会发射directoryChanged()信号,当监听的文件发生修改、重命名等操作时,会发射fileChanged()信号。所以,这个类在进行目录或文件监听时起作用。

总结: 监听队列中的文件发生改变时(删除修改文件),会触发fileChanged()信号。监听队列中的文件夹发生改变时(新增删除文件夹中的文件),会触发directoryChanged()信号。

QFileSystemWatcher的主要接口函数:

//函数原型                                           //功能
bool addPath(QString &path)                         //添加一个监听的目录或文件
QStringList addPaths(QStringList &paths)            //添加需要监听的目录或文件列表
QStringList directories()                           //返回监听的目录列表
QStringList files()                                 //返回监听的文件列表
bool removePath(QString &path)                      //移除监听的目录或文件
QStringList removePaths(QStringList &paths)         //移除监听的目录或文件列表

QFileSystemWatcher的两个信号:

void QFileSystemWatcher::directoryChanged(const QString &path)
void QFileSystemWatcher::fileChanged(const QString &path) 

使用时:
mainwindow.h中引入,并声明函数:

#include <QFileSystemWatcher>
public:
    QFileSystemWatcher *file_sys_watcher;
private slots:
    void on_directoryChanged(const QString path);
    void on_fileChanged(const QString path);

mainwindow.cpp中添加代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->pushButton->setText(u8"开始监听");
    ui->pushButton_2->setText(u8"结束监听");
    ui->pushButton_2->setEnabled(false);

    file_sys_watcher = new QFileSystemWatcher(this);     //初始化文件监听器
    file_sys_watcher->addPath("E:/2.jpg");   //监听文件
    file_sys_watcher->addPath("E:/lock/1");  //监听文件夹
}

void MainWindow::on_pushButton_clicked()   //开始监听
{//由于QFileSystemWatcher不需要使用事件,连接上以后就开始监听了,所以还是用按钮控制连接断开比较好
   connect(file_sys_watcher,SIGNAL(directoryChanged(QString)),this,SLOT(on_directoryChanged(QString)));
   connect(file_sys_watcher,SIGNAL(fileChanged(QString)),this,SLOT(on_fileChanged(QString)));
   ui->pushButton->setEnabled(false);
   ui->pushButton_2->setEnabled(true);
}

void MainWindow::on_pushButton_2_clicked()   //断开监听
{
    disconnect(file_sys_watcher,SIGNAL(directoryChanged(QString)),this,SLOT(on_directoryChanged(QString)));
    disconnect(file_sys_watcher,SIGNAL(fileChanged(QString)),this,SLOT(on_fileChanged(QString)));
    ui->pushButton->setEnabled(true);
    ui->pushButton_2->setEnabled(false);
}
//文件夹内容改变
void MainWindow::on_directoryChanged(const QString path)
{
    ui->label->setText(path+" changed!");
}
//文件内容改变
void MainWindow::on_fileChanged(const QString path)
{
    ui->label_2->setText(path+" changed!");
}

MainWindow::~MainWindow()
{
    delete ui;
}

运行结果:
在这里插入图片描述
点击开始监听,然后删除E:/2.jpg
在这里插入图片描述
接着再往E:/lock/1/中复制(或删除)一个文件:
在这里插入图片描述

6、QDataStream的读写:

写入数据流:
(注:以txt为例写入时,写入内容乱码)

QFile file1("E:/lock/1/2.jpg");
file1.open(QIODevice::ReadWrite);
QDataStream aStream(&file1);
aStream.setVersion(QDataStream::Qt_5_14);  //流版本号,写入和读取版本要兼容
QString a ="1";
aStream<<a;    //将a写入数据流文件中
//比如我把这字符串写入到那张图片中,然后图片就损坏了哈哈哈
file1.close();

读取数据流:
(注:如果程序不报错,但是读取不显示,可能就是流版本号不匹配造成的。可以创建一个文本,写入数据,然后尝试再读出来,要保证写入和读取的流版本号相同)

QFile file1("E:/lock/1/1.txt");
file1.open(QIODevice::ReadOnly);
QDataStream aStream(&file1);
aStream.setVersion(QDataStream::Qt_5_14);  //流版本号,写入和读取版本要兼容
QString aa="aba aba";
qint32 a;
aStream>>aa>>a;    //读取数据流

ui->label->setText(aa);
file1.close();

相关函数:

setByteOrder(QDataStream::ByteOrder)     //指定写入buffer时字节的顺序
writeRawData(const char *s,int len)     //字符串写入数据流
writeBytes(const char *s,uint len)      //字符串写入文件
readRawData(char *s,int len)     //读取基本数据类型
readBytes(char *&s,uint &len)       //读取字符串

setByteOrder()参数枚举常量:

QDataStream::BigEndian   //大端字节序
QDataStream::LittleEndian  //小端字节序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值