我有这个“data.txt”里面有这个文字:
1;Bob;Patino;43
/2;Chris;Metsen;46
/3;Rob;Pardo;37
/4;Megan;Fox;25
/5;Cara;Delevingne;21
我想用“Metzen”替换第二行“Metsen”的文本。 我可以通过重写整个数据来做到这一点,这很容易,但可能不方便大量的数据。
有没有办法通过重写特定数据(理想情况下使用QFile
和QTextStream
)来实现?
答案 0 :(得分:2)
从你的问题来看,你想要在内存映射IO中进行替换,这在一般情况下是不可能的。如果文件没有ASCII编码,或者替换文本的大小与它替换的文本大小相同,会发生什么?只要您需要插入'无论你喜不喜欢,你都在重写整个文件。此外,文件仍然必须完全读取才能搜索文本,因此无论如何它最终都不会成为优化。现代磁盘驱动器的写入速度为每秒数百到数千兆字节,因此您的写入时间可能可以忽略不计。
更不用说在尝试调试程序时,几乎100%肯定会破坏原始数据。即使你做得对,如果这个过程死了,你也会破坏原始数据。这不是正确的方法。
也就是说,使用QFile
和QTextStream
的正则表达式可以执行简单的子串替换 。该程序读入data.txt
,更正拼写错误,并将结果写入名为newData.txt
的新文件。
#include <QFile>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QRegularExpressionMatchIterator>
#include <QTextStream>
int main(int argc, char *argv[])
{
QFile data("C:/workspace/simpleQtProject/data.txt");
data.open(QIODevice::Text | QIODevice::ReadOnly);
QString dataText = data.readAll();
QRegularExpression re("Metsen");
QString replacementText("Metzen");
dataText.replace(re, replacementText);
QFile newData("C:/workspace/simpleQtProject/newData.txt");
if(newData.open(QFile::WriteOnly | QFile::Truncate)) {
QTextStream out(&newData);
out << dataText;
}
newData.close();
return 0;
}
注意: QRegularExpression
的优化性能实际上非常好,但由于在调试模式下禁用了JIT编译器,因此调试可能会很慢。有关实施的细微差别(以及发布性能的基准)的详细讨论,请参见peppe's blog post。
此外,如果您的正则表达式变得更复杂,并且您需要更好地控制替换的执行方式,则可以使用QRegularExpressionMatchIterator
语法和基于索引的QString::replace()
。这可以支持多个或命名的捕获组,或其他高级正则表达式功能。
#include <QFile>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QRegularExpressionMatchIterator>
#include <QTextStream>
int main(int argc, char *argv[])
{
QFile data("C:/workspace/simpleQtProject/data.txt");
data.open(QIODevice::Text | QIODevice::ReadOnly);
QString dataText = data.readAll();
// Using regex match iterator. Overkill for simple substring replacement, but scalable
// to very complex replacements.
QRegularExpression re("Metsen");
QString replacementText("Metzen");
QRegularExpressionMatchIterator itr = re.globalMatch(dataText);
while(itr.hasNext())
{
QRegularExpressionMatch match = itr.next();
dataText.replace(match.capturedStart(0), match.capturedLength(0), replacementText);
}
QFile newData("C:/workspace/simpleQtProject/newData.txt");
if(newData.open(QFile::WriteOnly | QFile::Truncate)) {
QTextStream out(&newData);
out << dataText;
}
newData.close();
return 0;
}