baizy77 发表于 2018-11-9 14:44:05

【独家连载】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]
查看完整版本: 【独家连载】Qt入门与提高: KS04-12 普通文本文件读写