基本上,如果我呼叫QFile::readLine
,将复制QFile
的整个行并将其粘贴到char*
或QByteArray
中。如果我想跳过999行以直接转到感兴趣的行(第1000行),那么我将无缘无故地复制并粘贴前999行,而我只想跳过它们。
我知道istream::ignore
使用户可以跳过任何数量的字符,直到找到分隔符为止,所以
std::ifstream file("file.txt");
for (auto i = 0u; i < 999u; ++i)
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::string str;
getline(file, str); // The 1,000th line is copied & pasted into str
将使您直接进入第1000行,而不会浪费任何时间进行复制和粘贴。如何使用QFile
做同样的事情?
答案 0 :(得分:1)
Qt没有用于在下一个特定字节出现之前查找文件而不输出读取数据的API。
尽管如此,您还是可以很亲近的
QFile
具有QIODevice::readLine(char *data, qint64 maxSize)
,它读入预分配的缓冲区,可以这样使用:
QFile f("..."); f.open(...);
int maxSize = 1024; // guess that 1kb will be enough per line
QByteArray lineData(maxSize, '\0');
int skipLines = 100;
while(f.readLine(lineData.data(), maxSize) > 0 && skipLines > 0) {
--skipLines;
}
此调用readLine()
重用了预先分配的缓冲区。
您可以看到,这里的关键部分是猜测哪种预分配大小最佳。如果您的行长超出了猜测的大小,那么您将跳过不到100行,因为每条较长的行都需要进行多次读取。
QTextStream
使用的内部缓冲区大小为16kb:
来自qtextstream.cpp:
static const int QTEXTSTREAM_BUFFERSIZE = 16384;
QIODevice
使用相同的缓冲区大小:
来自qiodevice_p.h:
#define QIODEVICE_BUFFERSIZE Q_INT64_C(16384)
旁注:
QTextStream
还具有readLineInto(QString *line, qint64 maxlen = 0)
,如果line
为0或读取行的长度为<maxlen
,则会动态重新分配line->capacity()
。但是,由于编码的原因,读入QString
总是比读入QByteArray
慢。
readLineInto(...)
并不像QByteArray
这样的功能。
使用QIODevice::getChar(char *c)
(在OP注释中提出)的解决方案也是合适的,因为它使用与readLine
相同的内部读取缓冲区,每次调用都有一些开销,但是调用者却没有不必担心行长会超过选定的缓冲区大小。