Qt5文件及磁盘处理
读写文本文件的方法通常有两种:一种是直接利用传统的QFile类方法;另一 种是利用更为方便的QTextStream类方法。
读写文本文件
QFile类读写文本
QFile类提供了读写文件的接口,这里首先介绍如何使用QFile类读写文本文件。
#include <QApplication>
#include <QFile>
#include <iostream>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFile file("1.txt");
if(file.open(QIODevice::ReadOnly))
{
char buffer[2048];
qint64 lineLen = file.readLine(buffer, sizeof(buffer));
if (lineLen != -1)
{
std::cout << buffer << std::endl;
}
}
return a.exec ();
}
打开文件使用 open()函数,关闭文件使 用close ()函数。此处的open()函数以只读方式打开文件,只读方式参数为 QIODevice::ReadOnly ,只写方式参数为 QIODevice::WriteOnly ,读写参数为 QIODevice: :ReadWrite。
QTextStream 类读写文本
QTextStream提供了更为方便的接口来读写文本,它可以操作QIODevice、 QByteArray和QString。使用QTextStream的流操作符,可以方便地读写单词、行 和数字。为了产生文本,QtextStream还提供了填充、对齐和数字格式化的选项。
#include <QApplication>
#include <QFile>
#include <iostream>
#include <QTextStream>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFile data("1.txt");
if(data.open(QFile::WriteOnly|QFile::Truncate))
{
QTextStream out(&data);
out << QObject::tr("score: ") << qSetFieldWidth (10) << left << 90 << endl;
}
data.close();
return a.exec ();
}
参数 QFile::Truncate 表示 将原来文件中的内容清空。输出时将格式设为左对齐,占10个字符位置。
QTextStream的格式化函数
函 数 | 功能描述 |
---|---|
qSetFieldWidth(int width) | 设置字段宽度 |
qSetPadChar(QChar ch) | 设置填充字符 |
qSetRea!NumberPercision(int precision) | 设置实数精度 |
其中,left操作符是QTextStream定义的类似于<iostream>中的流操作符。 QTextStream还提供了其他一些流操作符。
QTextStream的流操作符
操作符 | 作用描述 |
---|---|
bin | 设置读写的整数为二进制数 |
oct | 设置读写的整数为八进制数 |
dec | 设置读写的整数为十进制数 |
hex | 设置读写的整数为十六进制数 |
showbase | 强制显示进制前缀,如十六进制(Ox)、八进制(O)、二进制(Ob) |
fbrcesign | 强制显ZK符号(+, -) |
fbrcepoint | 强制显示小数点 |
noshowbase | 不显示进制前缀 |
nofbrcesign | 不显示符号 |
uppercasebase | 显示大写的进制前缀 |
lowercasebase | 显示小写的进制前缀 |
uppercasedigits | 用大写字母表示 |
lowercasedigits | 用小写字母表示 |
fixed | 固定小数点表示 |
scientific | 科学计数法表示 |
left | 左对齐 |
right | 右对齐 |
center | 居中 |
endl | 换行 |
flush | 清除缓冲 |
注意: 在 QTextStream 中使用的默认编码是 QTextCodec::codecForLocale() 函数返回的编码,同时能够自动检测Unicode,也可以使用QTextStream::setCodec (QTextCodec *codec)函数设置流的编码。
读写二进制文件
QDataStream类提供了将二进制文件串行化的功能,用于实现C++基本数据类 型,如char、short、 int、char *等的串行化。更复杂的串行化操作则是通过将数据 类型分解为基本类型来完成的。
#include <QApplication>
#include <QFile>
#include <iostream>
#include <QDataStream>
#include <QDate>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFile file("binary.dat");
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
QDataStream out(&file) ; //将数据序列化
out << QString(QObject::tr("测试名称:")); //字符串序列化
out << QDate::fromString("1994/09/25","yyyy/MM/dd");
out << (qint32) 19; //整数序列化
file.close ();
file.setFileName("binary.dat");
if(!file.open(QIODevice::ReadOnly))
{
std::cout << "error!";
return -1;
}
QDataStream in(&file) ; //从文件中读出数据
QString name;
QDate birthday;
qint32 age;
in >> name >> birthday >> age; //获取字符串和整数
std::cout << name.toStdString() << birthday.toString("yyyy/MM/dd").toStdString() << age << std::endl;
file.close ();
return a.exec ();
}
目录操作与文件系统
QDir类具有存取目录结构和内容的能力,使用它可以操作目录、存取目录或 文件信息、操作底层文件系统,而且还可以存取Qt的资源文件。
Qt使用“/”作为通用的目录分隔符和URL路径分隔符。如果在程序中使用“/” 作为目录分隔符,Qt会将其自动转换为符合底层操作系统的分隔符(如Linux使用 Windows 使用 “\”)。
QDir可以使用相对路径或绝对路径指向一个文件。isRelative。和isAbsolute() 函数可以判断QDir对象使用的是相对路径还是绝对路径。如果需要将一个相对路 径转换为绝对路径,则使用makeAbsolute()函数。
目录的路径可以通过path()函数返回,通过setPath()函数设置新路径。绝对路 径使用absolutePath()返回,目录名可以使用dirName()获得,它通常返回绝对路径 中的最后一个元素,如果QDir指向当前目录,则返回“.”。目录的路径可以通过 cd()和cdUp()改变。可以使用mkdir()仓ij建目录,rename()改变目录名。
判断目录是否存在可以使用exists(),目录的属性可以使用isReadable()、 isAbsolute()、isRelative()和isRoot()来获取。目录下有很多条目,包括文件、目录 和符号连接,总的条目数可以使用count()来统计。entryList()返回目录下所有条目 组成的字符串链表。文件可以使用remove()函数删除,删除目录用rmdir()。
文件大小及路径获取实例
#include <QApplication>
#include <QFile>
#include <iostream>
#include <QDir>
#include <QFileInfo>
qint64 du(const QString &path)
{
QDir dir(path);
qint64 size = 0;
foreach(QFileInfo fileinfo,dir.entryInfoList(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)
{
unit ='G';
curSize/=1024;
}
}
std::cout << curSize << unit <<" "<< qPrintable(path) << std::endl;
return size;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString path = QDir::currentPath();
du(path);
return a.exec ();
}
获取文件信息
QFileinfo类提供了对文件进行操作时获得的文件相关属性信息,包括文件名、 文件大小、创建时间、最后修改时间、最后访问时间及一些文件是否为目录、文件 或符号链接和读写属性等。
注意:
1.文件的所有权限可以由owner()、ownerld()、group()、groupld()等方法获 得。测试一个文件的权限可以使用Permission()方法。
2.为了提高执行的效率,QFilelnfo可以将文件信息进行一次读取缓存,这 样后续的访问就不需要持续访问文件了。但是由于文件在读取信息之后可能被其 他程序或本程序改变属性,所以QFilelnfo通过refresh()方法提供了 一种刷新机制 可以更新文件的信息,用户也可以通过setCaching()方法关闭这种缓冲功能。
3.QFilelnfo.可以使用绝对路径和相对路径指向同一个文件。其中,绝对路 径以“/”开头(在Windows中以磁盘符号开头),相对路径则以目录名或文件名 开头,isRelative()方法可以用来判断QFilelnfo使用的是绝对路径还是相对路径。 makeAbsolute()方法可以用来将相对路径转化为绝对路径。
监视文件和目录变化
在Qt中可以使用QFileSystemWatcher类监视文件和目录的改变。使用addPath() 函数监视指定的文件和目录时,如果需要监视多个目录,则可以使用addPaths()函 数加入监视。若要移除不需要监视的目录,则可以使用removePath()和removePaths() 函数。
当监视的文件被修改或删除时,产生一个fileChanged()信号。如果所监视的目 录被改变或删除,将产生directoryChanged()信号。
#include <QApplication>
#include <QFile>
#include <iostream>
#include <QDir>
#include <QFileSystemWatcher>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString path = QDir::currentPath();
QFileSystemWatcher *watcher = new QFileSystemWatcher();
watcher->addPath(path);
QObject::connect(watcher,&QFileSystemWatcher::directoryChanged,[](){
std::cout << "change" << std::endl;
});
return a.exec ();
}