QFile::readAll()
可能会导致内存问题并且std::getline()
速度很慢(原样::fgets()
)。
我遇到了类似的问题,我需要在QTableView
. 使用自定义模型,我解析文件以找到每行开头的偏移量。然后,当需要在表中显示数据时,我会读取该行并按需解析它。这会导致大量解析,但实际上速度足够快,不会注意到滚动或更新速度的任何滞后。
它还具有低内存使用率的额外好处,因为我不会将文件内容读入内存。使用这种策略,几乎任何大小的文件都是可能的。
解析代码:
m_fp = ::fopen(path.c_str(), "rb"); // open in binary mode for faster parsing
if (m_fp != NULL)
{
// read the file to get the row pointers
char buf[BUF_SIZE+1];
long pos = 0;
m_data.push_back(RowData(pos));
int nr = 0;
while ((nr = ::fread(buf, 1, BUF_SIZE, m_fp)))
{
buf[nr] = 0; // null-terminate the last line of data
// find new lines in the buffer
char *c = buf;
while ((c = ::strchr(c, '\n')) != NULL)
{
m_data.push_back(RowData(pos + c-buf+1));
c++;
}
pos += nr;
}
// squeeze any extra memory not needed in the collection
m_data.squeeze();
}
RowData
并且m_data
特定于我的实现,但它们仅用于缓存有关文件中一行的信息(例如文件位置和列数)。
我采用的另一种性能策略是用于QByteArray
解析每一行,而不是QString
. 除非您需要 unicode 数据,否则这将节省时间和内存:
// optimized line reading procedure
QByteArray str;
char buf[BUF_SIZE+1];
::fseek(m_fp, rd.offset, SEEK_SET);
int nr = 0;
while ((nr = ::fread(buf, 1, BUF_SIZE, m_fp)))
{
buf[nr] = 0; // null-terminate the string
// find new lines in the buffer
char *c = ::strchr(buf, '\n');
if (c != NULL)
{
*c = 0;
str += buf;
break;
}
str += buf;
}
return str.split(',');
如果您需要使用字符串而不是单个字符来分割每一行,请使用::strtok()
.