【独家连载】Qt入门与提高: KS04-12 普通文本文件读写
本帖最后由 baizy77 于 2019-7-2 20:35 编辑版权声明---------------------------------------------------------------------------------------------------------------------该文章原创于Qter开源社区(www.qter.org)作者: 女儿叫老白转载请注明出处!---------------------------------------------------------------------------------------------------------------------课程目录: 【独家连载】《Qt入门与提高-GUI产品开发》目录
网页版课程源码 提取码:1uy7----------------------------------------------------------------------------------------------------------------------引言----------------------------------------------------------------------------------------------------------------------在进行软件研发时,文件读写是经常碰到的场景。我们可以用文件来存储配置信息、序列化数据,甚至可以用文件作为接口来交互数据。文件的保存格式一般分为二进制格式和文本格式(也叫ASCII码格式)。我们今天先来看一下文本文件的读写。
正文---------------------------------------------------------------------------------------------------------------------- Qt提供了QFile类来处理文件操作,QFile派生自QIODevice。在本节的示例程序中,我们用到了之前章节中的公共类库,以便处理文件路径的解析。 在示例程序中,然后按照如下过程演示QFile的功能: 1. 写入一个初始文本文件, 2. 文本文件读取 3. 文本文件,追加写入 我们分别来看一下这些示例。场景1. 写入一个初始文本文件在本示例中,接口为initialize():/**
* @brief 文本文件初始化
*
* @return void
*/
void initialize(void)
{
QStringstrFileName;
strFileName =ns_train::getPath("$TRAINDEVHOME/test/chapter04/ks04_09/example01.txt");
QString strDir =ns_train::getDirectory(strFileName);
QDir dir;
dir.mkdir(strDir);
QFile file(strFileName);
} 为了防止文件路径不存在,我们先用QDir创建目录。然后我们定义一个QFile对象,并传入文件路径strFileName。这个文件路径通过公共类库中的getPath()接口获得。 然后,我们设置文件的打开方式: // 打开方式:只读、文本方式
if (!file.open(QFile::Truncate| QFile::WriteOnly | QFile::Text)) {
qDebug("open failed!file name is:%s", strFileName.toLocal8Bit().data());
return;
}
QFile的open接口描述如下:bool open(OpenMode flags);其中,OpenMode定义如下:enum OpenModeFlag {
NotOpen = 0x0000, // 文件未打开
ReadOnly = 0x0001,// 以只读方式打开文件,此时对文件调用写入接口会失败。
WriteOnly = 0x0002, // 以只写方式打开文件,此时对文件调用读取接口会失败。
ReadWrite = ReadOnly | WriteOnly, // 以读写方式打开。
Append = 0x0004, // 以追加方式打开,调用写入接口时,将默认追加到文件末尾。
Truncate = 0x0008,// 该模式将导致文件打开后被自动清空。
Text = 0x0010, // 以文本方式打开文件,如果不设置该选项,默认为二进制。
Unbuffered = 0x0020,// 无缓冲方式,慎用。即同步写硬盘,为false则异步写硬盘。
NewOnly = 0x0040,// 设置该值后,当文件已经存在时,open()返回失败。
ExistingOnly = 0x0080 // 设置该值后,当文件不存在时,open()返回失败。
};
Q_DECLARE_FLAGS(OpenMode, OpenModeFlag) 因为我们的接口功能是初始化一个文件,所以使用了QFile::Truncate。 因为是文本方式写入,所有使用了QFile::Text。 因为初始化时无需读取,只需写入,所以使用了QFile::WriteOnly。 然后,我们使用如下代码将strContent写入文件:if (false) {
file.write(strContent.toLocal8Bit());
}
else{
QTextStreamout(&file);
out<< strContent;
}
我们给出两种方案来写入文件,一种是调用write()接口写入文件;另外一种是利用QTextStream流来处理。大家可以把if(false)改为if(true)进行测试。 在代码最后,一定要记得关闭文件(file.close())。否则就要靠QFile析构时自动关闭,这样可不是友好的编程风格。场景2. 文本文件读取本示例代码中,我们用只读方式打开文件: QFile file(strFileName);
// 打开方式:只读、文本方式
if (!file.open(QFile::ReadOnly| QFile::Text)) {
qDebug("open failed!file name is:%s", strFileName.toLocal8Bit().data());
return;
}
// 输出整个文件的内容
QString strContent =file.readAll();
qDebug("File Opened, thisis the content:\n");
qDebug() << strContent;
// 将文件游标移到文件开头,否则的话,现在游标已经移动到文件尾,再执行后面的代码将无法读取到内容。
file.seek(0); 在上述代码中,我们用readAll()读取整个文件。在此之后,文件游标已经被移动到文件尾,通过seek()接口将文件游标移动到文件开头。 然后,我们介绍两种按行读取文件的方式(即:一次读取一行,遇到回车换行符就停止)。 方案1,使用QFile的readLine():const int c_maxNumber = 10240;
charbuf;
qint64nRead = 0;
qDebug("FileOpened, this is the lines:");
while(!file.atEnd()) {
nRead= file.readLine(buf, c_maxNumber);
strContent= buf;
strContent.remove("\r");
strContent.remove("\n");
qDebug("%s",strContent.toLocal8Bit().data());
} 通过上述代码可以看出,调用QFile::readLine()需要提供一个足够大的缓冲区并指明最多读取多少个字节,当一行的内容超过c_maxNumber时,即使没有读完整行也会停止读取,因此buf的尺寸和c_maxNumber要根据所要读取的文件内容设置成合适的值。 方案2,利用QTextStream进行读取:QTextStream in(&file);
while(!in.atEnd()) {
QStringline = in.readLine();
qDebug("%s",line.toLocal8Bit().data());
} 可以看出,使用QTextStream则没有这些限制。我们可以用QString直接存储读到的一行内容。这比方案1要简单多了。场景3. 文本文件,追加写入当我们要追加写入时,在打开文件时需要使用QFile::Append:QFile file(strFileName);
// 打开方式:只读、文本方式
//if (!file.open(QFile::ReadWrite |QFile::Text)) {
if (!file.open(QFile::ReadWrite |QFile::Append | QFile::Text)) {
return;
}
file.seek(0);// 使用QFile::Append打开文件后,游标默认在文件尾。
QString strContent =file.readAll();// readAll()导致文件的游标到达文件尾。 打开文件后,我们调用了seek(0)。原因是使用QFile::Append打开文件后,游标默认在文件尾。如果此时调用QFile::readAll(),将从游标当前位置开始向后读取,但是因为游标已经到文件尾部,所以readAll()将读取不到任何内容。所以我们使用seek(0)将游标移动到文件头。大家可以封掉seek(0),然后比较一下用不同QFile::Append有何不同。结语---------------------------------------------------------------------------------------------------------------------- 在本节中,我们介绍了通过QFile对文本文件进行操作的基本场景,大家可以练习一下。 如果您希望了解如何在文件开头追加内容、如何对文件进行拷贝、删除、改名、移动等操作,请来支持一下[课程视频] 吧。
上一节:KS04-11 编写自己的公共类库下一节:KS04-13 配置文件-XML格式
页:
[1]