お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"RE:TStrings 高速ファイル読み込み"

この発言は
#00629 本田勝彦 さんのTStrings 高速ファイル読み込み
に対するコメントです

本田勝彦 さんこんにちは。 バグってました(^^ゞ バッファに読み込む際、ファイル内の #13#10 が分断されると空白行が1行 余計に挿入されてしまいます。 $2000 バイト以上のファイルを読み込むと1/256の確率で発生することが 判明致しました。 バグレポートを下さった染川さんに多謝 m(_ _)m せっかくなので、#26 ( EOF ) 以降を読み込まないバージョンを書きます。 procedure LoadFromFile(Strings: TStrings; const FileName: String); const BufferSize = $2000; var I, ReadCount, LineCount: Integer; LineRemained: Boolean; S, Str: String; Buffer, P, Start: PChar; Fs: TFileStream; begin Strings.BeginUpdate; try Strings.Clear; Fs := TFileStream.Create(FileName, fmOpenRead); try Buffer := StrAlloc(BufferSize + 1); try // #13#10 をカウントする #26 以降は読み込まない LineCount := 0; LineRemained := False; repeat ReadCount := Fs.Read(Buffer^, BufferSize); if ReadCount > 0 then LineRemained := False; Buffer[ReadCount] := #0; P := Buffer; // バッファによって #13#10 が分断された場合のために if P^ = #10 then Inc(P); while not(P^ in [#0, #26]) do begin while not (P^ in [#0, #10, #13, #26]) do Inc(P); if P^ in [#10, #13] then Inc(LineCount) else LineRemained := True; if P^ = #13 then Inc(P); if P^ = #10 then Inc(P); end; if P^ = #26 then Break; until ReadCount = 0; if LineRemained then Inc(LineCount); // 取得した行数分の Capacity を確保 for I := 0 to LineCount - 1 do Strings.Add(''); // バッファを利用して読み込み #26 以降は読み込まない Fs.Seek(0, 0); LineCount := 0; Str := ''; repeat ReadCount := Fs.Read(Buffer^, BufferSize); Buffer[ReadCount] := #0; P := Buffer; // バッファによって #13#10 が分断された場合のために if P^ = #10 then Inc(P); while not(P^ in [#0, #26]) do begin Start := P; while not (P^ in [#0, #10, #13, #26]) do Inc(P); SetString(S, Start, P - Start); if P^ in [#0, #26] then Str := S else begin if Str <> '' then begin S := Str + S; Str := ''; end; Strings[LineCount] := S; Inc(LineCount); end; if P^ = #13 then Inc(P); if P^ = #10 then Inc(P); end; if P^ = #26 then Break; until ReadCount = 0; if Str <> '' then Strings[LineCount] := Str; finally StrDispose(Buffer); end; finally Fs.Free; end; finally Strings.EndUpdate; end; end; 利用法 var List: TStringList; FileName: String; begin if OpenDialog1.Execute then begin FileName := OpenDialog1.FileName; // LoadFromFile(Memo1.Lines, FileName); // なども可能 // LoadFromFile(ListBox1.Items, FileName); // 〃 List := TStringList.Create; try LoadFromFile(List, FileName); // 処理 finally List.Free; end; end; end; 本田勝彦 (* サンプル蔵ログファイルからヘルプファイルが作成できます。*) (* FDELPHI/LIB/06/114 を参照してください *) Original document by 本田勝彦 氏 ID:(VYR01647)



ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum