天天看點

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();
}
           

繼續閱讀