文件目录操作相关类:
QFile
:除了打开文件操作外,QFile
还有复制文件、删除文件等功能。
QCoreApplication
:用于提取应用程序路径、程序名等文件信息。
QFileInfo
:用于提取文件的信息,包括路径、文件名、后缀等。
QDir
:用于提取目录或文件信息,获取一个目录下的文件或目录列表,创建或删除目录和文件,文件重命名等操作。
QTemporaryDir
和QTemporaryFile
:用于创建临时目录和临时文件。
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);
}
}
运行结果:
QTemporaryDir
和QTemporaryFile
:
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 //小端字节序