前言
前幾天有同僚問我用
Qt
能不能将檔案讀取的指針向前移,她想周遊某個檔案找到插入的位置,然後将所需内容插入,我就想啊,這有啥不能的?
沒想到這個
QFile
不講武德,采用
QTextStream
的方法讀取,真的不能将指針移動。好在
QFile
它爸爸
QFileDevice
提供了一些方法…
來
pos()
來
seek()
我們的
QFile
,我勸
QTextStream
…
檔案操作
詳細内容自行翻閱文檔 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();
}