您的位置:首页 > 编程语言 > Qt开发

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

2017-09-04 19:17 295 查看
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()信号
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息