Qt5开发学习之文件及磁盘操作(十一)

来源:互联网 发布:猿题库数据从何来 编辑:程序博客网 时间:2024/06/05 06:39
Qt提供了QFile类进行文件操作。QFile类提供了读写文件的接口,可以读写文本文件、二进制文件、Qt资源文件。处理文本和二进制文件可以使用QTextStream和QDataStream类。处理临时文件可以使用QTemporaryFile,获取文本信息可以使用QFileInfo,处理目录可以使用QDir,监视文件和目录变化可以使用QFileStreamWatcher

读写文本文件

读写文本有两种方法:一种是直接使用传统的QFile类方法,一种是利用更为方便的QTextStream类方法。

1、QFile类读写文本:
建立一个Qt控制台应用试验QFile类
#include <QCoreApplication>#include <QFile>#include <QDebug>int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    // QFile 构造函数中打开文件    QFile file("QFile.txt");    // 只读打开文件    if (file.open(QIODevice::ReadOnly))    {        char buffer[2048];        // 返回读成功的字节数,失败返回-1        qint64 lineLen = file.readLine(buffer, sizeof(buffer));        if (lineLen != -1)        {            qDebug() << buffer;        }    }    return a.exec();}
2、QTextStream类读写功能
QTextStream类提供了更为方便的读写功能,他可以操作QIODevice、QByteArray和QString。使用QTextStream的流操作符可以方便的读写单词、行和数字。为了产生文本,QTextStream还提供了填充、对齐和数字格式化的选项。
建立一个Qt控制台程序试验QTextStream类:
#include <QCoreApplication>#include <QFile>#include <QTextStream>int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    // QFile 构造函数中打开文件    QFile file("QTextStream.txt");    // Truncate 若原先文件中有内容先清空    if (file.open(QFile::WriteOnly | QFile::Truncate))    {        QTextStream data(&file);        data << QObject::tr("Score:") << qSetFieldWidth(10) << left << 90 << endl;    }    return a.exec();}

读写二进制文件

QDataStream类提供了将二进制文件串行化的功能,用于实现C++基本数据类型的串行化,更复杂的串行化是通过分解数据类型完成的。

#include <QCoreApplication>#include <QFile>#include <QDataStream>#include <QtDebug>#include <QDate>int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    // 将数据以二进制的格式写入文件中    QFile file("binary.dat");    file.open(QFile::WriteOnly | QFile::Truncate);    QDataStream out(&file);    out << QString("柿子哥");    out << QDate::fromString("1992/4/30", "yyyy/MM/dd");    out << (qint32)25;    file.close();    // 从文件中读取数据并从二进制格式转换为本身的格式    file.setFileName("binary.dat");    if ( !file.open(QIODevice::ReadOnly) )    {        qDebug() << "Error";        return 0;    }    QDataStream in(&file);    QString name;    QDate birthday;    qint32 age;    in >> name >> birthday >> age;    qDebug() << name << birthday << age;    file.close();    return a.exec();}

目录操作与文件系统

QDir类具有存取目录结构和内容的能力,使用它可以操作目录、存取目录或文件信息、操作底层文件系统,还可以存取Qt的资源文件。

Qt使用“/”作为目录分隔符和URL路径隔离符。在程序中使用Qt会自动把它转换为匹配底层操作系统的分隔符。

QDir可以使用绝对路径和相对路径指向一个文件。isRelate()和isAbsolute()函数可以判断QDir对象使用的是相对路径还是绝对路径。如果需要将相对路径转换为相对路径可以使用makeAbsolute()。

目录的路径可以通过path()返回,通过setPath()设置新的路径。绝对路径使用absloutePath()返回,目录名可以使用dirName()获得,他通常返回绝对路径的最后一个元素,如果QDir指向当前目录则返回“.”。目录的路径可以通过cd()和cdUp()改变。mkdir()创建新的目录,rename()改变目录名。

判断目录是否存在使用exists(),目录的属性可以使用isReadable()、isAbsolute()、isRelative()和isRoot()来获取。目录下有很多条目,包括文件、目录和符号连接,总的条目数可以使用count()来统计。entryList()返回目录下所有条目组成的字符串链表。文件可以使用remove()删除,目录删除可以使用rmdir()

1、小程序得到文件大小和所在路径:

#include <QCoreApplication>#include <QFile>#include <QDir>#include <QStringList>#include <QtDebug>qint64 du(const QString &path){    QDir dir(path);    qint64 size = 0;    foreach (QFileInfo fileInfo, dir.entryList(QDir::Files)) {        size += fileInfo.size();    }    foreach (QString subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {        size += du(path + QDir::separator() + subDir);    }    char unit = 'B';    qint64 curSize = size;    if (curSize > 1024)    {        curSize /= 1024;        unit = 'K';        if (curSize > 1024)        {            curSize /= 1024;            unit = 'M';            if (curSize > 1024)            {                curSize /= 1024;                unit = 'G';            }        }    }    qDebug() << curSize << unit << "\t" << qPrintable(path) << endl;    return size;}int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    QStringList args = a.arguments();    QString path;    if (args.count() > 1)    {        path = argv[1];        qDebug() << "path" << endl;    }    else    {        path = QDir::currentPath();    }    qDebug() << path << endl;    du(path);    return a.exec();}

2、文件系统浏览

#include <QDialog>#include <QLineEdit>#include <QListWidget>#include <QVBoxLayout>#include <QDir>#include <QListWidgetItem>#include <QFileInfoList>class FileView : public QDialog{    Q_OBJECTpublic:    FileView(QWidget *parent = 0, Qt::WindowFlags f = 0);    ~FileView();    void showFileInfoList(QFileInfoList list);public slots:    void slotShow(QDir dir);    void slotDirShow(QListWidgetItem *item);private:    QLineEdit *fileLineEdit;    QListWidget *fileListWidget;    QVBoxLayout *mainLayout;};
#include "FileView.h"#include <QIcon>#include <QStringList>FileView::FileView(QWidget *parent, Qt::WindowFlags f)    : QDialog(parent, f){    setWindowTitle(tr("FileView"));    fileLineEdit = new QLineEdit(tr("/"));    fileListWidget = new QListWidget;    mainLayout = new QVBoxLayout(this);    mainLayout->addWidget(fileLineEdit);    mainLayout->addWidget(fileListWidget);    connect(fileLineEdit, SIGNAL(returnPressed()), this, SLOT(slotShow(QDir)));    connect(fileListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotDirShow(QListWidgetItem*)));    QString root = "/";    QDir rootDir(root);    QStringList string;    string << "*";    QFileInfoList list = rootDir.entryInfoList(string);    showFileInfoList(list);}FileView::~FileView(){}// 实现了用户可以双击浏览器中显示的目录进入下一级目录,或点击“..”返回上一级目录。// 顶部的编辑框显示当前所在的目录路径,列表中显示该目录下的所有文件。void FileView::showFileInfoList(QFileInfoList list){    // 清空列表控件    fileListWidget->clear();    for (unsigned int i = 0; i < list.count(); ++i)    {        QFileInfo tmpFileInfo = list.at(i);        if (tmpFileInfo.isDir())        {            QString name = tmpFileInfo.fileName();            QListWidgetItem *tmp = new QListWidgetItem(name);            fileListWidget->addItem(tmp);        }        else if (tmpFileInfo.isFile())        {            QString name = tmpFileInfo.fileName();            QListWidgetItem *tmp = new QListWidgetItem(name);            fileListWidget->addItem(tmp);        }    }}// 显示目录下所有文件void FileView::slotShow(QDir dir){    QStringList string;    string << "*";    // entryInfoList()按照某种过滤方式获得目录下的文件列表    QFileInfoList list = dir.entryInfoList(string, QDir::AllEntries, QDir::DirsFirst);    showFileInfoList(list);}// 根据用户的选择,显示下一级目录的所有文件void FileView::slotDirShow(QListWidgetItem *item){    // 将下一级目录文件名保存在str中    QString str = item->text();    QDir dir;    // 设置QDir对象的路径为当前路径    dir.setPath(fileLineEdit->text());    dir.cd(str);    // 刷新显示当前路径    fileLineEdit->setText(dir.absolutePath());    slotShow(dir);}

这里写图片描述


获取文件信息

QFileinfo类提供了对文件进行操作时获得的文件相关属性信息,包括文件名、文件大小、创建时间、最后修改时间、最后访问时间及一些文件是否为目录、文件或符号链接和读写属性等。
使用QFileinfo类获得文件信息的实例:

#include <QDialog>#include <QLabel>#include <QPushButton>#include <QLineEdit>#include <QCheckBox>class FileInfo : public QDialog{    Q_OBJECTpublic:    FileInfo(QWidget *parent = 0, Qt::WindowFlags f = 0);    ~FileInfo();public slots:    void slotFile();    void slotGet();private:    QLabel *fileLabel;    QLineEdit *fileLineEdit;    QPushButton *fileBtn;    QLabel *sizeLabel;    QLineEdit *sizeLineEdit;    QLabel *createLabel;    QLineEdit *createLineEdit;    QLabel *lastModifiedLabel;    QLineEdit *lastModifiedLineEdit;    QLabel *lastReadLabel;    QLineEdit *lastReadLineEdit;    QLabel *propertyLabel;    QCheckBox *isDirCheckBox;    QCheckBox *isFileCheckBox;    QCheckBox *isSymlinkCheckBox;    QCheckBox *isHiddenCheckBox;    QCheckBox *isReadableCheckBox;    QCheckBox *isWritableCheckBox;    QCheckBox *isExecutableCheckBox;    QPushButton *getBtn;};
#include "FileInfo.h"#include <QGridLayout>#include <QVBoxLayout>#include <QHBoxLayout>#include <QFileDialog>#include <QDateTime>FileInfo::FileInfo(QWidget *parent, Qt::WindowFlags f)    : QDialog(parent, f){    fileLabel = new QLabel(tr("文件名:"));    fileLineEdit = new QLineEdit;    fileBtn = new QPushButton(tr("文件"));    sizeLabel = new QLabel(tr("大小"));    sizeLineEdit = new QLineEdit;    createLabel = new QLabel(tr("创建时间:"));    createLineEdit = new QLineEdit;    lastModifiedLabel = new QLabel(tr("最后修改时间:"));    lastModifiedLineEdit = new QLineEdit;    lastReadLabel = new QLabel(tr("最后访问时间:"));    lastReadLineEdit = new QLineEdit;    propertyLabel = new QLabel(tr("属性:"));    isDirCheckBox = new QCheckBox(tr("目录"));    isFileCheckBox = new QCheckBox(tr("文件"));    isSymlinkCheckBox = new QCheckBox(tr("符号链接"));    isHiddenCheckBox = new QCheckBox(tr("隐藏"));    isReadableCheckBox = new QCheckBox(tr("读"));    isWritableCheckBox = new QCheckBox(tr("写"));    isExecutableCheckBox = new QCheckBox(tr("执行"));    getBtn = new QPushButton(tr("获取文件信息"));    QGridLayout *gridLayout = new QGridLayout;    gridLayout->addWidget(fileLabel, 0, 0);    gridLayout->addWidget(fileLineEdit, 0, 1);    gridLayout->addWidget(fileBtn, 0, 2);    gridLayout->addWidget(sizeLabel, 1, 0);    gridLayout->addWidget(sizeLineEdit, 1, 1, 1, 2);    gridLayout->addWidget(createLabel, 2, 0);    gridLayout->addWidget(createLineEdit, 2, 1, 1, 2);    gridLayout->addWidget(lastModifiedLabel, 3, 0);    gridLayout->addWidget(lastModifiedLineEdit, 3, 1, 1, 2);    gridLayout->addWidget(lastReadLabel, 4, 0);    gridLayout->addWidget(lastReadLineEdit, 4, 1, 1, 2);    QHBoxLayout *layout2 = new QHBoxLayout;    layout2->addWidget(propertyLabel);    layout2->addStretch();    QHBoxLayout *layout3 = new QHBoxLayout;    layout3->addWidget(isDirCheckBox);    layout3->addWidget(isFileCheckBox);    layout3->addWidget(isSymlinkCheckBox);    layout3->addWidget(isHiddenCheckBox);    layout3->addWidget(isReadableCheckBox);    layout3->addWidget(isWritableCheckBox);    layout3->addWidget(isExecutableCheckBox);    QHBoxLayout *layout4 = new QHBoxLayout;    layout4->addWidget(getBtn);    QVBoxLayout *mainLayout = new QVBoxLayout(this);    mainLayout->addLayout(gridLayout);    mainLayout->addLayout(layout2);    mainLayout->addLayout(layout3);    mainLayout->addLayout(layout4);    connect(fileBtn, &QPushButton::clicked, this, &FileInfo::slotFile);    connect(getBtn, &QPushButton::clicked, this, &FileInfo::slotGet);}FileInfo::~FileInfo(){}// 获取文件信息void FileInfo::slotFile(){    QString fileName = QFileDialog::getOpenFileName(this, "打开", "/", "files (*)");    fileLineEdit->setText(fileName);}void FileInfo::slotGet(){      QString file = fileLineEdit->text();      QFileInfo info(file);      qint64 size = info.size();      QDateTime create = info.created();      QDateTime lastModified = info.lastModified();      QDateTime lastRead = info.lastRead();      bool isDir = info.isDir();      bool isFile = info.isFile();      bool isSymlink = info.isSymLink();      bool isHidden = info.isHidden();      bool isReadAble = info.isReadable();      bool isWriteAble = info.isWritable();      bool isExecutable = info.isExecutable();      sizeLineEdit->setText(QString::number(size));      createLineEdit->setText(create.toString());      lastModifiedLineEdit->setText(lastModified.toString());      lastReadLineEdit->setText(lastRead.toString());      isDirCheckBox->setCheckState(isDir ? Qt::Checked : Qt::Unchecked);      isFileCheckBox->setCheckState(isFile ? Qt::Checked : Qt::Unchecked);      isSymlinkCheckBox->setCheckState(isSymlink ? Qt::Checked : Qt::Unchecked);      isHiddenCheckBox->setCheckState(isHidden ? Qt::Checked : Qt::Unchecked);      isReadableCheckBox->setCheckState(isReadAble ? Qt::Checked : Qt::Unchecked);      isWritableCheckBox->setCheckState(isWriteAble ? Qt::Checked : Qt::Unchecked);      isExecutableCheckBox->setCheckState(isExecutable ? Qt::Checked : Qt::Unchecked);}

监视文件和目录变化

Qt中可以使用QFileSystemWatcher类监视文件和目录的改变。使用addPath()或addPaths()监视指定的目录或文件。移除不需要监视的对象使用removePath()。当监视的文件被修改或删除时产生一个fileChanged()信号。如果所监视的目录被修改或删除产生一个directoryChanged()信号

原创粉丝点击