CStringList を使うと、複数の行を簡単に管理出来ます。しかし、エディタ等で大量の文書 をHDDから読み込んで、CStringList オブジェクトに設定する場合、 ファイルから1行づつ読み込み、CString オブジェクトを作り、 それを設定するというコードは非常に低速で、お話しになりません。
CStringList m_lineMgr; while( fgets(buffer, BUFSIZE, fo) != NULL ) { m_lineMgr.AddTail(CString(buffer)); // ここが、おそい }
CString::GetBuffer により、CString オブジェクトの文字列バッファを直接操作すること
ができます。メモリのアロック、フリー処理が発生しない分、高速になります(VC++では
オブジェクトの構築と解放に異様に時間がかかる)。
コードはたとえば以下のようになります(この例ではメモリマップトファイルを使って、ファイルを
メモリにマップしている)。GetBuffer でバッファアドレスを取得します。この時、バッファサイズ
が不足している時はリアロケートが行われます。最後に ReleaseBuffer でバッファアドレスを
リリースします。
..... CString rString; LPTSTR lpsz = rString.GetBuffer(bufSize); POSITION tailpos = m_lineMgr.GetTailPosition(); while( m_ptr < m_endptr ) { for(const char *p = m_ptr;p < m_endptr && *p != 0x0d && *p != 0x0a; p += 1) { if( *p == 0x1a ) { eof = 1; break; } } int size = p - m_ptr; // 1行の長さ if( eof && size == 0 ) break; if( size > bufSize - 1 ) { // バッファサイズが足りない場合は、拡張する rString.ReleaseBuffer(); lpsz = rString.GetBuffer(bufSize = size + 1); } memcpy(lpsz, m_ptr, size); // バッファを直接操作した方がはるかに高速! lpsz[size] = '\0'; m_lineMgr.InsertBefore(tailpos, rString); // いつもEOFの前に挿入 ..... } rString.ReleaseBuffer();
前のTips 次のTips 津田伸秀 のホームページに戻る。
Last Updated on 24-Aug-1996, Copyright (c) 1996 by Nobuhide Tsuda, All Right Reserved.
このホームページに関するご質問、ご要望、バグレポート等は
Nobuhide_Tsuda@jsn.justnet.or.jp
までメールをいただければ幸いです。