1、使用 QFile 进行文件操作
如何创建一个
QFile
对象,并使用该对象读取指定路径下的文本文件,其中QFile
是 Qt 提供的文件操作类,通过调用其成员函数readAll()
可以读取整个文件的内容,需要注意的是,在读取文件时需要先打开文件,最后在读取完成后关闭文件,否则会报错;
#include <QCoreApplication>
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 定义文件名
QString fileName = "C:\\cpp\\qt\\widget\\qq.txt";
// 创建文件对象
QFile file(fileName);
// 打开文件,并且以只读方式进行读取
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
// 读取文件内容
QByteArray fileData = file.readAll();
// 关闭文件
file.close();
// 输出读取的文件内容
qDebug() << "读取的文件内容:" << fileData;
} else {
// 如果文件打开失败,则输出错误信息
qDebug() << "打开文件失败!";
}
return a.exec();
}
2、使用 QTextStream 进行文本文件操作
创建一个
QTextStream
对象,并使用该对象向指定路径下的文本文件中写入数据,需要注意的是,在写入数据后需要关闭文件,否则会出现数据无法写入文件的情况;
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 定义文件名
QString fileName = "C:\\cpp\\qt\\widget\\ww.txt";
// 创建文件对象
QFile file(fileName);
// 打开文件,并且以写入方式进行操作
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
// 绑定 QTextStream 对象和文件对象
QTextStream out(&file);
// 写入数据到文件中
out << "Hello World!";
// 关闭文件
file.close();
// 重新打开文件并以只读方式进行操作
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
// 读取文件内容
QString fileContent = in.readAll();
// 关闭文件
file.close();
// 输出读取的文件内容
qDebug() << "读取的文件内容:" << fileContent;
} else {
// 如果文件打开失败,则输出错误信息
qDebug() << "打开文件失败!";
}
} else {
// 如果文件打开失败,则输出错误信息
qDebug() << "打开文件失败!";
}
return a.exec();
}
3、使用 QDataStream 进行二进制文件操作
创建一个
QDataStream
对象,并使用该对象向指定路径下的二进制文件中写入数据,需要注意的是,在写入数据后需要关闭文件,否则会出现数据无法写入文件的情况;
任务:把固定的char[256]这片区域写到文件中
方法一:最常见的流输出(QDataStream
流式操作<<)
void demo1(QFile& file)
{
qDebug()<<__FUNCTION__;
if(file.open(QIODevice::WriteOnly))
{
QDataStream out(&file);
char data[256];
memset(data,0,256*sizeof(char));
char* p = "this is QDataStream demo";
strcpy(data,p);
out<<data;
file.close();
}
else
{
qDebug()<<file.errorString();
}
}
//代码生成
0000 0019 7468 6973 2069 7320 5144 6174 6153 7472 6561 6d20 6465 6d6f 00
显示效果:
这样很明显不会得到想要的效果,因为QDataStream
遇到\0
就自动结束了。而且前面还加了一些其他的内容。会有 00 00 00 19
(t的ASCII为74)
方法二:QDataStream::writeBytes
函数(有Qt特有的标示+原始内存)
void demo2QDataStream(QFile& file)
{
qDebug()<<__FUNCTION__;
if(file.open(QIODevice::WriteOnly))
{
QDataStream out(&file);
char data[256];
memset(data,0,256*sizeof(char));
char* p = "this is QDataStream demo";
strcpy(data,p);
out.writeBytes(data,256);
file.close();
}
else
{
qDebug()<<file.errorString();
}
if(file.open(QIODevice::ReadOnly))
{
QDataStream out(&file);
char *data;
uint len;
out.readBytes(data,len);
if(len > 0)
{
qDebug()<<data;
delete[] data;
}
file.close();
}
else
{
qDebug()<<file.errorString();
}
}
注意,使用writeBytes
函数写的文件,必须用readBytes
函数读取,readBytes
函数是个工厂函数,会调用new[]
分配内存,因此需要调用delete[]
进行删除内存,否则会泄露。
生成的文件
虽然完整的把 发现能完整的把char[256]写入到文件中,但前面的00 00 01 00
是是Qt特有的标示,用于Qt自身的验证
方法三:int QDataStream::writeRawData(const char * s, int len)(只有原始内存)
int QDataStream::writeRawData(const char * s, int len)和int QDataStream::readRawData(char * s, int len)函数配对使用,用于写入最原始的内存,不想要Qt独有的一些信息
void demo3QDataStream(QFile& file)
{
qDebug()<<__FUNCTION__;
if(file.open(QIODevice::WriteOnly))
{
QDataStream out(&file);
char data[256];
memset(data,0,256*sizeof(char));
char* p = "this is QDataStream demo";
strcpy(data,p);
out.setVersion(QDataStream::Qt_5_12);
out.writeRawData(data,256);
file.close();
}
else
{
qDebug()<<file.errorString();
}
if(file.open(QIODevice::ReadOnly))
{
QDataStream in(&file);
char data[256];
memset(data,1,256*sizeof(char));
in.setVersion(QDataStream::Qt_5_12);
in.readRawData(data,256);
qDebug()<<data;
file.close();
}
else
{
qDebug()<<file.errorString();
}
}
生成的文件
就是我们想要的不加各种头尾的原始二进制了
总结:
1.在写出二进制时,如果需要仅仅写入原始的内存,记得使用int QDataStream::writeRawData(const char * s, int len)
函数,而不是QDataStream::writeBytes
函数
2.readBytes() 不需要事先分配好内存, 而readRawData() 需要事先分配好内存。
readRawData() 将数据读入一个预先分配好的char*;同样的数据也可以使用writeRawData() 函数写入data stream;readBytes() 先读取一个quint32值,该值被当做将要读取的数据的长度,然后读取相应字节的数据到预先定义好的char*中;writeBytes() 也同理,先写入一个quint32的数据长度值,紧接着写入相应数据。这两种函数,数据的编码和解码要有我们自己负责。