天天看点

Qt - 如何在文件中插入数据前言文件操作插入数据

前言

前几天有同事问我用

Qt

能不能将文件读取的指针向前移,她想遍历某个文件找到插入的位置,然后将所需内容插入,我就想啊,这有啥不能的?

没想到这个

QFile

不讲武德,采用

QTextStream

的方法读取,真的不能将指针移动。好在

QFile

它爸爸

QFileDevice

提供了一些方法…

pos()

seek()

我们的

QFile

,我劝

QTextStream

Qt - 如何在文件中插入数据前言文件操作插入数据

文件操作

详细内容自行翻阅文档 QFile Class & QTextStream Class

QFileDevice

QFile *file = new QFile("test.txt");
    qDebug() << "file open:" << file->open(QIODevice::ReadWrite |QIODevice::Text);
    //Read
    int maxsize = 20;
    qDebug() << "read():" << file->read(maxsize);
    qDebug() << "readAll():" << file->readAll();

	//Write
	file->write("Write OK.");
           

QTextStream

QFile *file = new QFile("test.txt");
    qDebug() << "file open:" << file->open(QIODevice::ReadWrite|QIODevice::Text);
    QTextStream txtOutput(file);

    //Read 1
    int maxsize = 20;
    txtOutput.read(maxsize);
    txtOutput.readAll();

    //Write 1
    txtOutput << "Write OK.";

    //Read 2
    QString line;
    while (txtOutput.readLineInto(&line)) {
        qDebug() << "line:" << line;
    }
           

插入数据

回到前面提到的问题,插入数据。

QFileDevice

为我们提供了

pos()

用于获取当前指针位置,

seek()

用于设置指针位置。

方法一

如果文件内容较少,我们可以采用这种方式将文件全部读取,然后在通过

insert()

插入数据,最后覆盖写回文件。

QByteArray fileData(file.readAll());
fileData.insert(20, data);
file.seek(0);
file.write(fileData);
file.close();
           

方法二

如果文件内容较多,可采用以下方法,思路是:

  • 采用只读形式打开文件,随后遍历各行,同时不断写到新文件。
  • 找到插入位置后,记录位置,插入内容,再将原文件剩下的内容写入。
  • 关闭文件,删除原文件,最后将新文件重命名。
/**
 * @brief MainWindow::insertData
 * @param path 文件路径
 * @param filename 文件名
 * @param lineindex 插入行号
 * @param insertdata 插入数据
 * @param posoffset pos 偏移值,一些文件类型可能需要,可调试使用
 * @param backnewline 插入前是否需要换行,可调试使用
 * @param afternewline 插入后是否需要换行,可调试使用
 */
void MainWindow::insertData(QString path,QString filename,int lineindex,QByteArray insertdata,int posoffset,bool backnewline,bool afternewline){

    QFile *fileR = new QFile(path + filename);
    qDebug() << "fileR open:" << fileR->open(QIODevice::ReadOnly |QIODevice::Text);

    QFile *fileW = new QFile("new_" + path + filename);
    qDebug() << "fileR open:" << fileW->open(QIODevice::WriteOnly |QIODevice::Text);

    for(int i = 0; i < lineindex-1; i++){
        fileR->readLine();
    }

    // 记录当前位置
    int pos = fileR->pos() + posoffset;
    fileR->seek(0);

    // 拷贝
    QByteArray buff = fileR->read(pos);
    fileW->write(buff);

    //追加数据
    if(backnewline)
        fileW->write("\n");
    fileW->write(insertdata);
    if(afternewline)
       fileW->write("\n");

    //写入剩余内容
    buff = fileR->readAll();
    fileW->write(buff);

    //删除原文件
    fileR->remove();

    //重命名文件
    fileW->rename(filename);

    fileR->close();
    fileW->close();
}
           

继续阅读