一.概述
QFile 类支持对文件进行读取、写入、删除、重命名、拷贝等操作,它既可以操作文件文件,也可以操作二进制文件。
二.QFile方法
1.使用 QFile 读写文件之前必须先打开文件,调用 open() 成员方法即可,常用的语法格式为:
bool QFile::open(OpenMode mode)
mode 参数用来指定文件的打开方式,下表罗列了此参数的可选值以及各自的含义:
表 1 QFile文件打开方式 | |
打开方式 | 含 义 |
QIODevice::ReadOnly | 只能对文件进行读操作 |
QIODevice::WriteOnly | 只能对文件进行写操作,如果目标文件不存在,会自行创建一个新文件。 |
QIODevice::ReadWrite | 等价于 ReadOnly | WriteOnly,能对文件进行读和写操作。 |
QIODevice::Append | 以追加模式打开文件,写入的数据会追加到文件的末尾(文件原有的内容保留)。 |
QIODevice::Truncate | 以重写模式打开,写入的数据会将原有数据全部清除。注意,此打开方式不能单独使用,通常会和 ReadOnly 或 WriteOnly 搭配。 |
QIODevice::Text | 读取文件时,会将行尾结束符(Unix 系统中是 "\n",Windows 系统中是 "\r\n")转换成‘\n’;将数据写入文件时,会将行尾结束符转换成本地格式,例如 Win32 平台上是‘\r\n’。 |
根据需要,可以为 mode 参数一次性指定多个值,值和值之间用|分割。比如:
QIODevice::ReadOnly | QIODevice::Text:表示只允许对文件进行读操作,读取文件时,会将行尾结束符转换为 '\n';
QIODevice::WriteOnly | QIODevice::Text:表示只允许对文件进行写操作,将数据写入文件时,会将行尾结束符转换为本地格式;
QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text:表示对文件进行写操作,写入的数据会存放到文件的尾部,同时数据中的行尾结束符转换为本地格式。
注意,传递给 mode 参数的多个值之间不能相互冲突,比如 Append 和 Truncate 不能同时使用。
如果文件成功打开,open() 函数返回 true,否则返回 false。
2.读文件(Read)
当打开方式指定可以读文件的时候 从QIODevice继承下来的读文件公有方法:
qint64 read(char * data, qint64 maxSize)
以二进制的方式进行读取;将设备中maxSize字节读入数据保存在data中,并返回读取的字节数;当没有更多数据可供读取时,返回0;读过流的末尾为错误,返回-1 。
QByteArray read(qint64 maxSize)
从设备中读取maxSize字节,并将读取的数据作为QByteArray(字节数组)返回。
QByteArray readAll()
从设备读取所有可用数据,并将其作为QByteArray返回。
qint64 readLine(char * data, qint64 maxSize)
从设备中读取一行ASCII字符(最大为maxSize – 1字节),将字符存储在data中,并返回读取的字节数。如果一行不能被读取,但是没有错误发生,这个函数返回0。如果发生错误,将返回可读内容的长度,如果未读,则返回-1,结束的“\0”字节总是附加到数据中,因此maxSize必须大于1。
QByteArray readLine(qint64 maxSize = 0)
从设备中读取一行,但不超过maxSize字符,并以字节数组的形式返回结果。
使用完必须关闭流:QFile对象.close();
3.写文件(Write)
从QIODevice继承下来的写文件公有方法:
qint64 write(const char * data, qint64 maxSize)
将data提取maxSize字节数写到设备中(由于字体编码问题,中文字符为3个字节)。返回实际写入的字节数,如果发生错误则返回-1。
qint64 write(const char * data)
将以零结尾的8-bit字符串中的数据写入设备。返回实际写入的字节数,如果发生错误则返回-1。这等价于 QIODevice::write(data, qstrlen(data));
qint64 write(const QByteArray & byteArray)
将byteArray的内容写入设备。返回实际写入的字节数,如果发生错误则返回-1
4.QFile的公有成员函数
QFile除了构造函数外还有一些其它的公有成员函数哦!
(1)copy() :拷贝文件
bool QFile::copy(const QString & newName)
静态 bool QFile::copy(const QString & fileName, const QString & newName)
copy函数说明: 1.将当前指定的文件复制到名为newName的文件中。 2.如果成功返回true;否则返回false。 3.注意,如果一个名为newName的文件已经存在,copy()返回false(即QFile不会覆盖它)。 4.源文件在复制之前关闭 例子:
bool QFile::copy(const QString & newName) 的写法:
bool isSaveOK = file.copy(SavePath);
(2)exists() :判断文件存不存在
bool QFile::exists() const
静态 bool QFile::exists(const QString & fileName)
exists()函数说明: 1.如果fileName文件存在,则返回true;否则返回false。
(3)rename() :重命名文件
bool QFile::rename(const QString & newName)
静态 bool QFile::rename(const QString & oldName, const QString & newName)
rename说明: 1.将当前由fileName()指定的文件重命名为newName。如果成功返回true;否则返回false。 2.如果一个名为newName的文件已经存在,rename()返回false(即, QFile不会覆盖它)。 3.在重命名之前关闭文件。 4.如果重命名操作失败,Qt将尝试将该文件的内容复制到newName,然后删除该文件,只保留newName。 5.如果复制操作失败或无法删除此文件,则删除目标文件newName以恢复旧状态
(4)setFileName() :设置文件名称
void QFile::setFileName(const QString & name)
setFileName说明: 1.设置文件的名称。 2.名称可以没有路径、相对路径或绝对路径。 3.如果文件已经被打开,不要调用这个函数。 4.如果文件名没有路径或相对路径,则使用的路径将是open()调用时应用程序的当前目录路径。 5.注意,目录分隔符“/”适用于Qt支持的所有操作系统。
(5)link() :创建快捷方式
bool QFile::link(const QString & linkName)
静态 bool QFile::link(const QString & fileName, const QString & linkName)
link说明: 1.创建一个名为linkName的链接,该链接指向当前由fileName()指定的文件。 2.链接是什么取决于底层文件系统(可能是Windows上的快捷方式,也可能是Unix上的符号链接)。如果成功返回true;否则返回false。 3.此函数不会覆盖文件系统中已存在的实体;在这种情况下,link()将返回false,并将error()设置为返回RenameError。 4.注意:要在Windows上创建有效的链接,linkName必须有一个.lnk文件扩展名
(6)symLinkTarget() :获取快捷方式路径字符串
静态 QString QFile::symLinkTarget(const QString & fileName)
QString QFile::symLinkTarget() const
symLinkTarget说明: 1.返回文件名指定的符号链接(或Windows上的快捷方式)所引用的文件或目录的绝对路径,如果文件名不对应于符号链接,则返回空字符串。 2.此名称可能不表示现有文件;它只是一个字符串。 3.如果符号链接指向一个现有文件,则QFile::exists()返回true。
(6)size() :返回文件大小
qint64 QFile::size() const
size说明: 1.对于开放随机访问设备,此函数返回设备的大小。 2.对于打开的顺序设备,将返回bytesAvailable()。 3.如果设备关闭,返回的大小将不反映设备的实际大小。
三.代码示例
1. QFile 类读写文本文件的过程:
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
//创建 QFile 对象,同时指定要操作的文件
QFile file("D:/demo.txt");
//对文件进行写操作
if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){
qDebug()<<"文件打开失败";
}
//向文件中写入两行字符串
file.write("C语言中文网\n");
file.write("http://c.biancheng.net");
//关闭文件
file.close();
//重新打开文件,对文件进行读操作
if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){
qDebug()<<"文件打开失败";
}
//每次都去文件中的一行,然后输出读取到的字符串
char * str = new char[100];
qint64 readNum = file.readLine(str,100);
//当读取出现错误(返回 -1)或者读取到的字符数为 0 时,结束读取
while((readNum !=0) && (readNum != -1)){
qDebug() << str;
readNum = file.readLine(str,100);
}
file.close();
return 0;
}
执行程序,“C语言中文网” 和 “http://c.biancheng.net” 先写入 D 盘的 demo.txt 文件,然后再从文件中将它们读取出来。
2. QFile 读写二进制文件的过程:
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
//指定要写入文件的数据
qint32 nums[5]={1,2,3,4,5};
//写入文件之前,要将数据以二进制方式存储到字节数组中
QByteArray byteArr;
byteArr.resize(sizeof(nums));
for(int i=0;i<5;i++){
//借助指针,将每个整数拷贝到字节数组中
memcpy(byteArr.data()+i*sizeof(qint32),&(nums[i]),sizeof(qint32));
}
//将 byteArr 字节数组存储到文件中
QFile file("D:/demo.dat");
file.open(QIODevice::WriteOnly);
file.write(byteArr);
file.close();
//再次打开文件,读取文件中存储的二进制数据
file.open(QIODevice::ReadOnly);
QByteArray resArr = file.readAll();
//输出读取到的二进制数据
qDebug()<<"resArr: "<<resArr;
//将二进制数据转化为整数
char* data = resArr.data();
while(*data){
qDebug() << *(qint32*)data;
data += sizeof(qint32);
}
return 0;
}
执行程序,demo.dat 文件中会存储 {1,2,3,4,5} 这 5 个整数的二进制形式,同时输出以下内容:
resArr: “\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00”