前言
前几天有同事问我用
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();
}