16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"改行を含む複数の任意長文字列を保存"
この発言に対し以下のコメントが寄せられています
#00991 かとちん さん RE:改行を含む複数の任意長文字列を保存
memoなどに書き込んだ改行を含む文字列を複数一つのファイルに
書きだし/読み込みするためのクラスを作りました。
このサンプルは一旦全てメモリに読み込むのであまり大きな
データには向きません。(10Mくらいまでは問題ないと思いますが)
deleteの例はありませんが、Itemsに対して普通にdeleteできますので
ListBoxのItemsを使うのと同じ要領で使って下さい。
ファイルのフォーマットは
count:integer データの数
size0:integer
size1
・
・
size[count-1] ここまで各データの長さ
Data0:size0 バイトの文字列
Data1:size1 バイトの文字
・
・
Data[count-1]
という構成です。
フォームにTMainMenu TLabel TMemoをひとつづつおいて、
TMainMenuは
N1:読み込み
N2:書き出し
add1:sf:TStrFile にmemo1.textを追加
Nexst1:次の文字列をmemo1に表示
Prior1:前の文字列をmemo1に表示
エラー処理は最小限しかしておりませんので、必要に応じて
実装して下さい。(Next1でcount-1を超えるとエラーになりますし
Prior1で0を下回ってもエラーになるはず)
//***************************
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls, Menus;
type
//改行を含む文字列を読み込み/書きだしするクラス
TStrFile=Class
public
Items:TStringList;
constructor create;
destructor destroy;
procedure LoadFromFile(FileName:String);
procedure SaveToFile(FileName:String);
end;
TForm1 = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
add1: TMenuItem;
Memo1: TMemo;
Next1: TMenuItem;
Prior1: TMenuItem;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure add1Click(Sender: TObject);
procedure Next1Click(Sender: TObject);
procedure Prior1Click(Sender: TObject);
private
{ Private 宣言 }
sf:TStrFile;
index:integer;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
{ TStrFile }
constructor TStrFile.create;
begin
items:=TStringList.Create;
end;
destructor TStrFile.destroy;
begin
items.Free;
end;
//指定されたファイルからデータを読み込む
procedure TStrFile.LoadFromFile(FileName: String);
var
count,i:integer;
fs:TFileStream;
sizes:array of integer;
buf:integer;
sbuf:PChar;
begin
fs:=TFileStream.Create(FileName,fmOpenRead);
try
fs.Position:=0;//不要かも
//データ数を読み込む
fs.read(count,sizeOf(count));
setLength(sizes,count);
//各データの長さを得ておく
for i:= 0 to count-1 do
begin
fs.Read(buf,sizeOf(buf));
sizes[i]:=buf;
end;
//各データの長さ情報を元に各データを読み込んでitemsに登録
for i:=0 to count-1 do
begin
sbuf:=StrAlloc(sizes[i]+1);
fs.read(sbuf^,sizes[i]);
sbuf[sizes[i]]:=#0;
items.add(String(sbuf));
strDispose(sbuf);
end;
finally
fs.free;
end;
end;
//ファイルフォーマットに則って書きだし
procedure TStrFile.SaveToFile(FileName: String);
var
count,i:integer;
fs:TFileStream;
sizes:array of integer;
buf:integer;
sbuf:String;
begin
fs:=TFileStream.Create(FileName,fmCreate);
try
count:=Items.Count;
fs.Write(count,sizeOf(count));
setLength(sizes,count);
for i:= 0 to count-1 do
begin
buf:=Length(items[i]);
fs.write(buf,sizeOf(buf));
end;
for i:=0 to count-1 do
begin
sbuf:=items[i];
fs.write(PChar(sbuf)^,Length(sbuf));
end;
finally
fs.free;
end;
end;
//具体的使用法
procedure TForm1.FormCreate(Sender: TObject);
begin
index:=0;
sf:=TStrFile.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
sf.free;
end;
//読み込み
procedure TForm1.N1Click(Sender: TObject);
begin
sf.LoadFromFile('c:\pooo');
end;
//書きだし
procedure TForm1.N2Click(Sender: TObject);
begin
sf.SaveToFile('c:\pooo');
end;
//データの追加
procedure TForm1.add1Click(Sender: TObject);
begin
sf.items.add(memo1.text);
end;
//次のデータを表示
procedure TForm1.Next1Click(Sender: TObject);
begin
inc(index);
if (index>=0) and (index<sf.items.Count) then
begin
Label1.caption:=inttostr(index);
memo1.text:=sf.items[index];
end;
end;
//前のデータを表示
procedure TForm1.Prior1Click(Sender: TObject);
begin
dec(index);
if (index>=0) and (index<sf.items.Count) then
begin
Label1.caption:=inttostr(index);
memo1.text:=sf.items[index];
end;
end;
end.
☆☆☆ かわいいコードにゃ旅をさせよう いざサンプル蔵へ!! ☆☆☆
99/12/15(水) 01:18 凛(MXB01744)
Original document by 凛 氏 ID:(MXB01744)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|