|
テキストファイルかバイナリファイルか、一括して読み込むか部分的に読み込むかで使用する API が変わってきます。 テキストファイル †一括してメモリに読み込み、一括して書き込む †TStringList を使います。
var
lines: TStringList;
i: Integer;
begin
lines := TStringList.Create;
try
// ファイルを読み込む
lines.LoadFromFile('textfile.txt');
// アルファベットをすべて大文字に変換
for i := 0 to lines.Count-1 do
lines[i] := UpperCase(lines[i]);
// ファイルを書き込む
lines.SaveToFile('textfile.txt');
finally
ines.Free;
end;
end;
先頭から一行ずつ読み込み、一行ずつ書き込む †AssignFile, Reset, Rewrite, Readln, Writeln, CloseFile を使います。
{$APPTYPE CONSOLE}
var
f: Text;
line: string;
begin
AssignFile(f, 'c:\test.txt');
Reset(f);
try
while not Eof(f) do
begin
// 一行読み込む
Readln(f, line);
line := Uppercase(line);
// ファイル変数を省略すると
// 標準出力へ出力します。
Writeln(line);
end;
finally
CloseFile(f);
end;
end.
ログを出力する †既に存在するファイルの末尾にテキストを追加していく場合は、AssignFile, Append, Rewrite, Writeln を使います。 var
f: TextFile;
begin
{$i+}
AssignFile(f, ChangeFileExt(ParamStr(0), '.log'));
try
Append(f);
except
on EInOutError do
Rewrite(f);
end;
try
Writeln(f, DateTimeToStr(Now), ': ログを追加');
finally
CloseFile(f);
end;
end;
バイナリファイル †一括してメモリに読み込む †TMemoryStream を使います。 type
TByteArray = array [0..MaxInt-1] of Byte;
PByteArray = ^TByteArray;
var
ms: TMemoryStream;
p: PByteArray;
i: Integer;
begin
ms := TMemoryStream.Create;
ms.LoadFromFile('file.dat');
// 読み込んだバッファへのポインタを取得
p := ms.Memory;
// 各バイトを1増やす
for i := 0 to ms.Size-1 do
Inc(p^[i]);
ms.SaveToFile('file.dat');
ms.Free;
end;
先頭から順番に読み込む †TFileStream を使います。バイナリファイルを読み書きする最も一般的な方法です。 // ファイルをコピーする
var
src, dest: TFileStream;
buf: array[0..4095] of Byte;
numread:
begin
src := TFileStream.Create('src.txt', fmOpenRead);
dest := TFileStream.Create('dest.txt', fmCreate);
while True do
begin
numread := fs.Read(buf, SizeOf(buf));
// すべて読み込んだら抜ける。
if numread = 0 then
break;
dest.Write(buf, numread);
end;
end;
ランダムアクセスする †TFileStreamのPosition プロパティ、Seek メソッドを使ってアクセスする場所を指定できます。 // ファイルの10バイト目を1増やす。
var
fs: TFileStream;
b: Byte;
begin
fs := TFileStream.Create('file.dat', fmOpenReadWrite);
fs.Position := 10;
fs.Read(b, SizeOf(b));
Inc(b);
fs.Position := 10;
fs.Write(b, SizeOf(b));
fs.Free;
end;
その他 †BlockRead / BlockWrite †古い関数です。あまり使うメリットはありません。 Win32API †CreateFile, ReadFile, WriteFile, CloseFileを使って読み書きします。非常に柔軟なアクセスが可能です。 ファイルマッピングオブジェクトを使用する †CreateFileMapping, MapViewOfFile を使用するとファイルをメモリ上の配列のように扱うことが出来ます。ファイル全域にランダムアクセス可能でしかもファイルをすべて読み込むことがないのでメモリ効率がいいです。 procedure TForm1.Button1Click(Sender: TObject); var hFile: THandle; hFileMapping: THandle; p: Pointer; fileSize: DWORD; begin fileSize := 100; // TODO:既にファイルが存在するならファイルサイズを取得する。 hFile := CreateFile( 'mapfile.txt', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); Win32Check(hFile <> INVALID_HANDLE_VALUE); try hFileMapping := CreateFileMapping( hFile, nil, PAGE_READWRITE, 0, fileSize, nil); Win32Check(hFileMapping <> 0); try p := MapViewOfFile( hFileMapping, FILE_MAP_WRITE, 0, 0, 0); // ファイルサイズは指定しない。 Win32Check(p <> nil); try // TODO:ポインタpの[0..fileSize-1]に対して読み書きする finally Win32Check(UnmapViewOfFile(p)); end; finally Win32Check(CloseHandle(hFileMapping)); end; finally Win32Check(CloseHandle(hFile)); end; end; |
DelWiki 内検索広告 |