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() << "文件发生变化";
}

  

posted @   TechNomad  阅读(188)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
点击右上角即可分享
微信分享提示