在Qt中读取文本文件

3

我想读取一个巨大的文本文件,将字符串根据逗号(,)分割并存储在数组中。那么如何实现呢?是否有类似于badaOS中的StringTokenizer的类可以完成此操作?我尝试了QFile但它无法读取整个文件。


你考虑过使用 std::ifstream 吗? - Oswald
不要一次性读取整个文件,逐行读取它。 - Kamil Klimek
2
这个巨大的文件是否有非常长的行?如果没有,QTextStream :: readLine()和QString :: split()将对您有所帮助。 - Sergei Tachenov
我已经使用正则表达式来获取所有匹配项。如果你愿意,你可以将代码重构为一个漂亮的小函数。 - kayleeFrye_onDeck
5个回答

10

QTextStream让您可以逐行读取文本

QFile file(hugeFile);
QStringList strings;
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
    QTextStream in(&file);
    while (!in.atEnd()) {
        strings += in.readLine().split(";"); 
    }
}

2
好的解决方案,但正如我之前提到的,如果有超长的行或根本没有行分隔符,这种方法无法很好地工作。我还想知道为什么这两个答案在示例中使用“;”,而问题中提到了“,”。 - Sergei Tachenov
使用“;”作为分隔符是事实上的标准。 - Henrikki

1

你可以使用文件流。

QFile file = new QFile(hugeFile);      
file.open(QIODevice.OpenModeFlag.ReadOnly);       
QDataStream inputStream = new QDataStream(file);
QStringList array;
QString temp;

while(!inputStream.atEnd()) {
  inputStream >> temp;
  array << temp.split(";");
}

请注意,这是未经测试的(伪)代码,希望它能有所帮助。

你所说的“无法运行”是什么意思?有没有支持Qt的真正文本文件的操作系统?VMS有这些文件,但不支持Qt。在Unix、Linux和Windows上,“文本”只是普通文件的特殊解释。 - MSalters
4
@MSalters,QDataStream没有为字符串重载operator>>。答案中的代码甚至无法编译。 - Sergei Tachenov

0

这段代码无法捕获逗号后面的空格。如果这不可接受,请随意优化正则表达式。您可能还可以减少顶部的包含量。我只是想彻底一些。我在一个1600行的文件上测试了它,在Qt 5.6中似乎处理得很好。

#include <QCoreApplication>
#include <QFile>
#include <QIODevice>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QRegularExpressionMatchIterator>
#include <QString>
#include <QStringList>
#include <QTextStream>

int main(int argc, char * argv[])
{
    QCoreApplication app(argc, argv);

    QFile file("C:\\PathToFile\\bigFile.fileExt");
    QStringList lines;
    QStringList matches;
    QString match;

    file.open(QIODevice::ReadOnly | QIODevice::Text);
    while(!file.atEnd())
    {
      lines << file.readLine();
    }
    file.close();

    QRegularExpression regex("(^|\\s|,)\\K\\w.*?(?=(,|$))");
    QRegularExpressionMatchIterator it;

    foreach (QString element, lines)
    {
        it = regex.globalMatch(element);

        while(it.hasNext())
        {
            QRegularExpressionMatch qre_match = it.next();
            match = qre_match.captured(0);
            matches << match;
        }
    }

    return 0;
}

0

您可以随时读取文件的一部分:

QFile file( ... );
file.read(1000); // reads no more than 1000 bytes

或者你可以逐行读取你的文件:

file.readLine();

但您必须处理一个字符串被分成两个部分的情况。


0

如果是一个非常巨大的文件,则可以在 file.atEnd() 为 false 的同时使用 file.read(an_appropriate_number) 进行读取。

读取一块(使用 file.read()),将其添加到临时字符串缓冲区中并搜索 ',' (例如使用 QString 的 contains() 方法)。 如果它包含一个 ',' ,则拆分它(使用 QString 的 split() 方法):前 X 部分(读取的1000个字符可能包含多个标记)将包含找到的标记,而最后一个不是完整的标记。 因此,将临时字符串切换到拆分的最后一部分,并读取另一块(直到遇到 file.atEnd()),然后将其附加到临时字符串缓冲区中。 除非您的标记很大,否则这将有效工作。 在遇到 file.atEnd() 后不要忘记处理最后一个缓冲文本 :)

或者作为替代方案,您可以逐个字符地读取文件并手动检查 ',',但是最好读取超过1个字符(如果读取更多则效率更高)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接