Qt之文件系统
一、文本文件的读写
1.QFile读取文本文件
QFile类是直接与IO设备打交道,进行文件读写操作的类,使用QFile可以直接打开或保存文本文件。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | void MainWindow::on_btn_clicked() { QString curPath = QDir::currentPath(); QString dlgTitle = "打开一文件" ; QString filter = "程序文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)" ; QString fileName = QFileDialog::getOpenFileName( this , dlgTitle, curPath, filter); if (fileName.isEmpty()) { return ; } QFile file(fileName); if (!file.exists()) { qDebug() << "文件不存在" ; return ; } if (!file.open(QIODevice::ReadOnly |QIODevice::Text)) { qDebug() << "文件打开失败" ; return ; } m_pTextEdit->setPlainText(file.readAll()); file.close(); } |
定义QFile对象变量fileName时将文件名传递给它,检查文件存在后,通过open()函数打开文件。
QFile::open()函数打开文件时需要传递QIODevice::OpenModeFlag枚举类型的参数,决定文件以什么方式打开,QIODevice::OpenModeFlag类型的主要取值如下:
- QIODevice::ReadOnly:以只读方式打开文件,用于载入文件。
- QIODevice::WriteOnly:以只写方式打开文,用于保存文件。
- QIODevice::ReadWrite:以读写方式打开。
- QIODevice::Append:以添加模式打开,新写入文件的数据添加到文件尾部。
- QIODevice::Truncate:以截取方式打开文件,文件原有的内容全部被删除。
- QIODevice::Text:以文本方式打开文件,读取时"\n"被自动翻译为换行符,写入时字符串结束符会自动翻译为系统平台的编码,如Windows平台下是“\r\n”。
这些取值可以组合,例如QIODevice::ReadOnly | QIODevice::Text表示只读和文本方式打开文件;文本内容读取结束后,需要调用QFile::close()函数关闭文件。
2.QFile写入文本文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | void MainWindow::on_btn_clicked() { QString curPath = QDir::currentPath(); QString dlgTitle = "另存为一个文件" ; QString filter = "程序文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)" ; QString fileName = QFileDialog::getSaveFileName( this , dlgTitle, curPath, filter); if (fileName.isEmpty()) { return ; } QFile file(fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug() << "文件打开失败" ; return ; } QString str = m_pTextEdit->toPlainText(); //整个内容作为字符串 QByteArray strBytes = str.toUtf8(); //转换为字节数组 qint64 ret = file.write(strBytes, strBytes.length()); //写入文件 if (ret != strBytes.length()) { qDebug() << "文件写入失败" ; } file.close(); } |
为了保存文件,用open()打开文件时,使用的模式是QIODevice::WriteOnly | QIODevice::Text。使用WriteOnly隐含着Truncate,即删除文件原有内容,并将QString类型的文本内容通过toUtf8()函数转换为UTF8编码的字节数组strBytes,然后调用QFile::write()函数将字节数组内容写入文件。
二、QFile和QTextSTream结合读写文本文件
1.QTextSTream读取文件
QTextStream与IO读写设备结合,为数据读写提供了一些方便的方法的类,QTextStream可以与QFile、QTemporaryFile、QBuffer、QTcpSocket和QUdpSocket等IO设备类结合使用。
下面的示例将QFile和QTextStream结合,读取文本文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | void MainWindow::on_btn_clicked() { QString curPath = QDir::currentPath(); QString dlgTitle = "打开一文件" ; QString filter = "程序文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)" ; QString fileName = QFileDialog::getOpenFileName( this , dlgTitle, curPath, filter); if (fileName.isEmpty()) { return ; } QFile file(fileName); if (!file.exists()) { qDebug() << "文件不存在" ; return ; } if (!file.open(QIODevice::ReadOnly |QIODevice::Text)) { qDebug() << "文件打开失败" ; return ; } QTextStream stream(&file); //用文本流读取文件 stream.setAutoDetectUnicode( true ); //自动检测Unicode,才能显示汉字 m_pTextEdit->setPlainText(stream.readAll()); file.close(); } |
在创建QTextStream实例时传递一个QFile对象,这样,QFile对象和QTextStream对象就结合在一起了,利用QTextStream可读写文件,如果文本文件里有汉字,需要设定为自动识别Unicode码,即调用setAutoDetectUnicode(true)函数。
在上述代码里,使用QTextStream::readAll()函数一次读出文件全部文本内容,但是QTextStream还提供了一些其他方便使用的接口函数,如使用QTextStream可以方便的实现逐行读取文本文件内容。对openTextByStream()函数稍作修改,使其以逐行的方式读取文件内容,这种方式适用于需要逐行解析字符串的内容的应用。
示例代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | void MainWindow::on_btn_clicked() { QString curPath = QDir::currentPath(); QString dlgTitle = "打开一文件" ; QString filter = "程序文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)" ; QString fileName = QFileDialog::getOpenFileName( this , dlgTitle, curPath, filter); if (fileName.isEmpty()) { return ; } QFile file(fileName); if (!file.exists()) { qDebug() << "文件不存在" ; return ; } if (!file.open(QIODevice::ReadOnly |QIODevice::Text)) { qDebug() << "文件打开失败" ; return ; } QTextStream stream(&file); //用文本流读取文件 stream.setAutoDetectUnicode( true ); //自动检测Unicode,才能显示汉字 QString str; while (!stream.atEnd()) { str = stream.readLine(); //读取文件的一行文本 m_pTextEdit->appendPlainText(str); } file.close(); } |
QTextStream::readLine()函数通过自动识别换行符来读取一行字符串。
2.QTextSTream写入文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | void MainWindow::on_btn_clicked() { QString curPath = QDir::currentPath(); QString dlgTitle = "打开一文件" ; QString filter = "程序文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)" ; QString fileName = QFileDialog::getSaveFileName( this , dlgTitle, curPath, filter); if (fileName.isEmpty()) { return ; } QFile file(fileName); if (!file.exists()) { qDebug() << "文件不存在" ; return ; } if (!file.open(QIODevice::WriteOnly |QIODevice::Text)) { qDebug() << "文件打开失败" ; return ; } QTextStream stream(&file); //用文本流读取文件 stream.setAutoDetectUnicode( true ); //自动检测Unicode,才能显示汉字 QString str = m_pTextEdit->toPlainText(); stream << str; //写入文本流 file.close(); //关闭文件 } |
因为在写入文件时,直接使用了流的写入操作,所以,使用QTextStream进行文件读写是比较方便的。
三、解决中文乱码的问题
在使用QTextStremd读写有中文内容的文本文件时,为了能正确识别Unicode码,需要调用setAutoDetectUnicode(true)。设置QTextStream可以自动识别Unicode码,如果不做此设置,读取文件的中文可能会乱码,无法正常显示。
为了能解决Unicode的识别问题,可以在应用程序中做全局的设置,使用应用程序支持Unicode,方法是在main()函数中使用QTextCodec类进行编码设置。
示例代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 | int main( int argc, char *argv[]) { QTextCodec *pCodec = QTextCodec::codecForName( "UTF-8" ); QTextCodec::setCodecForLocale(pCodec); QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } |
四、文件目录操作
1.文件目录操作相关的类
Qt为文件和目录操作提供了一些类,利用这些类可以方便的实现一些操作,Qt提供的与文件和目录操作相关的类包括以下几个:
- QCoreApplication:用于提取应用程序路径、程序名等文件信息。
- QFile:除了打开文件操作外,QFile还有复制文件、删除文件等功能。
- QFileInfo:用于提取文件的信息,包括路径、文件名、后缀等。
- QDir:用于提取目录或文件信息,获取一个目录下的文件或目录列表,创建或删除目录和文件,文件重命名等操作。
- QTemporaryDir和QTemporaryFile:用于创建临时目录和临时文件。
- QFileSystemWatcher:文件和目录监听类,监听目录下文件的添加、删除等变化,监听文件修改变化。
这些类基本覆盖了文件操作需要的主要功能,有些功能还在某些类里重复出现,例如QFile和QDir都具有删除文件、判断文件是否存在的功能。
2.QCoreApplication类
QCoreApplication是为无GUI应用提供事件循环的类,是所有应用程序类的基类,其子类QGuiApplication为GUI界面的应用程序提供流控制和主要的设定,QGuiApplication的子类QApplication为基于QWidget的应用程序提供支持,包括界面的初始化等。创建的Qt Widget Application都是基于QApplication的,在main()函数里可以看到QApplication的应用。
QCoreApplication提供了一些有用的静态函数,可以获取应用程序的名称、启动路径等信息。
1 2 3 4 5 6 7 8 9 10 | /* 返回应用程序启动路径 */ qDebug() << QCoreApplication::applicationDirPath(); /* 返回应用程序的带有目录的完整文件名 */ qDebug() << QCoreApplication::applicationFilePath(); /* 返回应用程序名称,无路径、无后缀 */ qDebug() << QCoreApplication::applicationName(); /* 返回动态加载库文件时,应用程序搜索的目录列表 */ qDebug() << QCoreApplication::libraryPaths(); /* 退出应用程序 */ QCoreApplication:: exit (); |
3.QFile类
前面使用QFile类进行文件的操作,应用了QFile::open()函数。除了打开文件提供读写操作外,QFile还有一些静态函数或成员函数用于文件操作。
QFile的一些静态函数:

QFile的一些成员函数:
4.QFileInfo类
QFileInfo类的接口函数提供文件的各种信息,QFileInfo对象创建时可以指定一个文件名作为当前文件,也可以用setFile()函数指定一个文件作为当前文件。
示例代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | void MainWindow::on_btn_clicked() { QString curPath = QDir::currentPath(); QString dlgTitle = "打开一文件" ; QString filter = "程序文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)" ; QString fileName = QFileDialog::getOpenFileName( this , dlgTitle, curPath, filter); if (fileName.isEmpty()) { return ; } QFileInfo fileInfo; fileInfo.setFile(fileName); qDebug() << "fileInfo.absoluteFilePath():" << fileInfo.absoluteFilePath(); qDebug() << "fileInfo.absolutePath():" << fileInfo.absolutePath(); qDebug() << "fileInfo.fileName():" << fileInfo.fileName(); qDebug() << "fileInfo.filePath():" << fileInfo.filePath(); qDebug() << "fileInfo.path():" << fileInfo.path(); qDebug() << "fileInfo.size():" << fileInfo.size(); qDebug() << "fileInfo.baseName():" << fileInfo.baseName(); qDebug() << "fileInfo.completeBaseName():" << fileInfo.completeBaseName(); qDebug() << "fileInfo.suffix():" << fileInfo.suffix(); qDebug() << "fileInfo.completeSuffix():" << fileInfo.completeSuffix(); qDebug() << "fileInfo.isDir():" << fileInfo.isDir(); qDebug() << "fileInfo.isFile():" << fileInfo.isFile(); qDebug() << "fileInfo.isExecutable():" << fileInfo.isExecutable(); qDebug() << "fileInfo.exists():" << fileInfo.exists(); qDebug() << "QFileInfo::exists(fileName):" << QFileInfo::exists(fileName); } |
5.QDir类
QDir是进行目录操作的类,在创建QDir对象时传递一个目录字符串作为当前目录,然后QDir函数就可以针对当前目录或目录下的文件进行操作,下面列表是QDir的一些静态函数:

下面是QDir的一些公共接口函数:

获取目录下的目录或文件列表的函数entryList()需要传递QDir::Filter枚举类型的参数以获取不同的结果。QDir::Filter枚举类型的常用取值如下:
- QDir::AllDirs:列出所有目录名
- QDir::Files:列出所有文件
- QDir::Drives:列出所有盘符(Unix系统下无效)
- QDir::NoDotAndDotDot:不列出特殊的符号,如"."和“..”
- QDir::AllEntries:列出目录下所有项目
6.QTemporaryDir和QTemporaryFile
QTemporaryDir是用于创建、删除临时目录的类,其主要函数如下所示:

QTemporaryDir示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 | void MainWindow::on_btn_clicked() { QTemporaryDir tempDir; if (tempDir.isValid()) { // 临时目录成功创建 QString tempPath = tempDir.path(); qDebug() << "临时目录路径:" << tempPath; } else { qWarning() << "无法创建临时目录!" ; return ; } } |
QTemporaryFile是Qt框架中用于创建临时文件的类。它可以帮助您在需要时创建一个临时文件,并在不再需要时自动删除它。
QTemporaryFile示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | void MainWindow::on_btn_clicked() { QTemporaryFile tempFile; //使用open()方法打开临时文件 if (tempFile.open()) { // 临时文件成功打开 qDebug() << "临时文件路径:" << tempFile.fileName(); } else { qWarning() << "无法打开临时文件!" ; return ; } //写入数据到临时文件 QTextStream stream(&tempFile); stream << "这是一个临时文件的内容" << endl; tempFile.close(); tempFile. remove (); // 显式删除临时文件 } |
7.QFileSystemWatcher类
QFileSystemWatcher是对目录和文件进行监听的类,把某些目录或文件添加到QFileSystemWatcher对象的监听列表后,当目录下发送文件新建、删除等操作时会发生directoryChanged()信号,当监听的文件发生修改,重名等操作时,会发射fileChanged()信号,所以这个类在进行目录或文件监听时起作用。
QFileSystemWatcher的主要接口函数如下所示:

QFileSystemWatcher有两个信号,分别是目录变化和文件变化时发射的信号:
1 2 | QFileSystemWatcher::directoryChanged( const QString &path); QFileSystemWatcher::fileChanged( const QString &path); |
示例代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | void MainWindow::on_btn_clicked() { QFileSystemWatcher *pFileSystemWatcher = new QFileSystemWatcher( this ); connect(pFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this , &MainWindow::on_directory_changed); connect(pFileSystemWatcher, &QFileSystemWatcher::fileChanged, this , &MainWindow::on_file_changed); QString curPath = QDir::currentPath(); QString dlgTitle = "打开一文件" ; QString filter = "程序文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)" ; QString fileName = QFileDialog::getOpenFileName( this , dlgTitle, curPath, filter); if (fileName.isEmpty()) { return ; } QFileInfo fileInfo; fileInfo.setFile(fileName); QString filePath = fileInfo.absolutePath(); pFileSystemWatcher->addPath(filePath); //添加监听目录 pFileSystemWatcher->addPath(fileName); //添加监听文件 } void MainWindow::on_directory_changed() { qDebug() << "目录发生变化" ; } void MainWindow::on_file_changed() { qDebug() << "文件发生变化" ; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器