QFile::readAll()
メモリの問題を引き起こす可能性があり、std::getline()
低速です (現状のまま::fgets()
)。
非常に大きな区切りテキスト ファイルを .xml ファイルで解析する必要があるという同様の問題に直面しました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
私の実装に固有のものですが、ファイル内の行に関する情報 (ファイルの位置や列の数など) をキャッシュするためにのみ使用されます。
私が採用したもう 1 つのパフォーマンス戦略は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(',');
各行を 1 文字ではなく文字列で分割する必要がある場合は、 を使用します::strtok()
。