ファイル操作について質問させてください。
普通ファイルを他のアプリケーションが使用していると、
Delphiからは開けませんよね。
ところが、一部のテキストエディタなどは読み取り専用とすることで
ファイルを開くことができます(MicrosoftOffice等)。
あれはどうやっているのでしょうか?
LoadFromFileなら開けると思うけど。
内部的には、LoadFromFileは以下のように「読み取り専用 + 他からの書き込みを禁止」で開いている。
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
回答ありがとうございます。
TextFileとAssignfileで読み込んでいたので、読み込めなかったのだろうと思います。
ところでFilestreamを使用して60万行ほどあるテキストを読み込みたいのですが、
ファイルを開いてから一行ずつ読み込む方法がわからないんです。
いままではReadlnで読み込んでいたのですが、
Filestreamで同じことをするにはどうしたらいいのでしょうか?
どうやらRead関数を使う場合一行あたりの長さがわかっていないといけないようなので、
不定である今回の場合は使えないようだということがわかっています。
ご教授いただければと思います。
>ご教授いただければと思います。
"ご教授"などということは、真っ平御免こうむりたい。
"教えてほしい"ということなら、以下の通り。
ファイルからの一行単位の読み込みは効率が悪いので、バッファサイズ単位で読み込む。
procedure TForm1.Button1Click(Sender: TObject);
const
BUF_SIZE = $4000-1;
var
NumRead: DWORD;
PosRead: INT64;
pT, pH, Buf: PChar;
begin
with TOpenDialog.Create(nil) do try
if not Execute then exit;
GetMem(Buf, BUF_SIZE+1);
PosRead := 0;
try
with TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite) do try
repeat
NumRead := Read(Buf^, BUF_SIZE);
Buf[NumRead] := #0;
pH := Buf;
pT := pH;
while pT-Buf < BUF_SIZE do begin
while not(pT^ in [#0,#10,#13]) do inc(pT);
if pT^ <> #0 then begin
pT^ := #0;
Memo1.Lines.Add(pH); // 切り出した一行の処理
inc(pT, 2); // CRLFを読み飛ばし
pH := pT;
end else begin
pT := pH;
break;
end;
end;
inc(PosRead, pT - Buf);
Position := PosRead;
until NumRead < BUF_SIZE;
Memo1.Lines.Add(pH); // 最終行切り出し処理
finally
Free;
end;
finally
FreeMem(Buf);
end;
finally
Free;
end;
end;
ありがとうございました。
無事に解決することができました。
すいません。
再度お教え願います。
真っ平御免さんの方法を使わせていただきました。
読み込みは無事に成功したのですが、やはり読み込み速度が上がりません。
どうも
>while not(pT^ in [#0,#10,#13]) do inc(pT);
で一文字ずつ読んでいるのが原因だと思われるのですが・・・
ReadlnやObject.Linesなどのように一行を高速に読むことはできないのでしょうか?
ツイート | ![]() |