テキストファイルを1行ずつ処理したい。昔、私はファイルを次の場所にロードしましたStringList
:
slFile := TStringList.Create();
slFile.LoadFromFile(filename);
for i := 0 to slFile.Count-1 do
begin
oneLine := slFile.Strings[i];
//process the line
end;
問題は、ファイルが数百メガバイトになると、大量のメモリを割り当てなければならないことです。一度に1行を保持するのに十分なメモリしか必要ない場合。(さらに、ステップ 1 でファイルのロード中にシステムがロックされている場合、進行状況を実際に示すことはできません)。
Delphi が提供するネイティブで推奨されるファイル I/O ルーチンを使用してみました。
var
f: TextFile;
begin
Reset(f, filename);
while ReadLn(f, oneLine) do
begin
//process the line
end;
問題Assign
は、ロックせずにファイルを読み取るオプションがないことです (つまりfmShareDenyNone
)。前のstringlist
例は、次のように変更しない限り、no-lock もサポートしませんLoadFromStream
。
slFile := TStringList.Create;
stream := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone);
slFile.LoadFromStream(stream);
stream.Free;
for i := 0 to slFile.Count-1 do
begin
oneLine := slFile.Strings[i];
//process the line
end;
そのため、ロックが保持されていなくても、ファイル全体をメモリにロードすることに戻りました。
Assign
/に代わるものはありReadLn
ますか 、共有ロックを取得せずにファイルを1行ずつ読み取ることができますか?
Win32 CreateFile
/に直接入りたくないので、バッファの割り当てと, ,のReadFile
検出に対処する必要があります。CR
LF
CRLF
メモリ マップ ファイルについて考えましたが、ファイル全体が仮想メモリに収まらない (マップされない) 場合や、ファイルのビュー (断片) を一度にマップする必要がある場合に問題があります。醜くなり始めます。
私はただReset
欲しいfmShareDenyNone
!