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

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_OBJECT

public:
    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_OBJECT

public:
    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()信号

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值