C
cgs3300
Unregistered / Unconfirmed
GUEST, unregistred user!
想实现从文件中读写TDataSet的Fields,实现方法如下, 现在的问题是从文件中读出的TField对象无法在TDataSet及DBGrid中正常工作,试了好久,头有点晕了。
code:
{******************************************************************************}
{* }
{* 单元名称:读写TDataSet的Fields对象 }
{* 创建日期:2006.01.07 }
{* 单元作者:cgs }
{* 备 注: }
{* 开发平台:PWin2000pro + Delphi 7.0 }
{* 版权所有 (C) 2006 cgs_studio }
{* 更新记录: }
{* }
{******************************************************************************}
unit uCKFields;
interface
uses
Classes, sysutils, DB;
type
TCKFields = class(TObject)
private
FDataSet: TDataSet;
function GetFields: TFields;
function GetField(index: integer): TField;
public
constructor Create(ds: TDataSet);
procedure SaveToFile(FileName:string);
procedure LoadFromFile(FileName:string);
procedure SaveToStream(Stream:TStringStream);
procedure LoadFromStream(Stream:TStringStream);
procedure SaveToIni(iniFileName,Section:string);
procedure LoadFromIni(iniFileName,Section:string);
property DataSet:TDataSet read FDataSet;
property Fields:TFields read GetFields;
property Items[index:integer]:TField read GetField; Default;
end;
function ComponentToString(Component: TComponent): string;
function StringToComponent(Value: string): TComponent;
implementation
uses strutils ,inifiles;
function ComponentToString(Component: TComponent): string;
var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(Component);
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStream, StrStream);
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free;
end;
finally
BinStream.Free
end;
end;
function StringToComponent(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value);
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStream, BinStream);
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(nil);
finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;
{ TCKFields }
constructor TCKFields.Create(ds: TDataSet);
begin
inherited Create;
FDataSet:=ds;
end;
function TCKFields.GetField(index: integer): TField;
begin
result:=nil;
if FDataSet<>nil then
result:=FDataSet.Fields[index];
end;
function TCKFields.GetFields: TFields;
begin
result:=nil;
if FDataSet<>nil then
result:=FDataSet.Fields;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromFile }
{ 说明: 从文本文件中读取读取Fields }
{ 日期: 2006.01.07 }
{ 参数: FileName: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.LoadFromFile(FileName: string);
var
ssFile:TStrings;
stmStr:TStringStream;
begin
if FDataSet=nil then exit;
ssFile:=TStringlist.Create;
try
ssFile.LoadFromFile(FileName);
if ssFile.Count=0 then exit;
stmStr:=TStringStream.Create(ssFile.Text);
try
LoadFromStream(stmStr);
finally
stmStr.Free;
end;
finally
ssFile.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromIni }
{ 说明: 从INI文本文件中读取读取Fields }
{ 日期: 2006.01.07 }
{ 参数: iniFileName, Section: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.LoadFromIni(iniFileName, Section: string);
const
sKey= 'CKFields%d';
var
i:integer;
ini:TInifile;
stmStr:TStringStream;
stmTmp:TMemoryStream;
begin
ini:=TInifile.Create(iniFileName);
try
stmStr:= TStringStream.Create('');
try
stmTmp:=TMemoryStream.Create;
try
stmStr.Seek(0,soFromBeginning);
i:=0;
while true do
begin
stmTmp.SetSize(0);
ini.ReadBinaryStream(Section,format(sKey,),stmTmp);
if stmTmp.Size =0 then break;
stmTmp.Seek(0,soFromBeginning);
stmStr.CopyFrom(stmTmp,stmTmp.Size);
inc(i);
end;
LoadFromStream(stmStr);
finally
stmTmp.Free;
end;
finally
stmStr.Free;
end;
finally
ini.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromStream }
{ 说明: 从流中读取Fields }
{ 日期: 2006.01.07 }
{ 参数: Stream: TStringStream }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.LoadFromStream(Stream: TStringStream);
var
ssAll,ss:TStrings;
i:integer;
Component:TComponent;
begin
if FDataSet=nil then exit;
ss:=TStringlist.Create;
ssAll:=TStringlist.Create;
try
ssAll.Text:=Stream.DataString;
if ssAll.Count=0 then exit;
FDataSet.Fields.Clear;
for i:=0 to ssAll.Count-1 do
begin
if LowerCase(LeftStr(ssAll,6))='object' then
begin
ss.Clear;
ss.Add(ssAll);
end
else if LowerCase(LeftStr(ssAll,3))='end' then
begin
ss.Add(ssAll);
Component:= StringToComponent(ss.Text);
FDataSet.Fields.Add(TField(Component));
end
else if trim(ssAll)='' then
begin
break;
end
else
ss.Add(ssAll);
end;
finally
ssAll.Free;
ss.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToFile }
{ 说明: 保存到文本文件 }
{ 日期: 2006.01.07 }
{ 参数: FileName: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.SaveToFile(FileName: string);
var
ssFile:TStrings;
stmStr:TStringStream;
begin
if FDataSet=nil then exit;
ssFile:=TStringlist.Create;
try
stmStr:= TStringStream.Create('');
try
SaveToStream(stmStr);
ssFile.Text:=stmStr.DataString;
ssFile.SaveToFile(FileName);
finally
stmStr.Free;
end;
finally
ssFile.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToIni }
{ 说明: 保存到INI文件 }
{ 日期: 2006.01.07 }
{ 参数: iniFileName, Section: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.SaveToIni(iniFileName, Section: string);
const
BuffSize=40;
sKey= 'CKFields%d';
var
i:integer;
ini:TInifile;
stmStr:TStringStream;
stmTmp:TMemoryStream;
Buffer:Array[0..BuffSize-1] of char;
begin
ini:=TInifile.Create(iniFileName);
try
ini.EraseSection(Section);
stmStr:= TStringStream.Create('');
try
stmTmp:=TMemoryStream.Create;
try
SaveToStream(stmStr);
stmStr.Seek(0,soFromBeginning);
for i:=0 to stmstr.Size div BuffSize -1 do
begin
FillChar(Buffer,length(Buffer),#0);
stmStr.Read(Buffer,length(Buffer));
stmTmp.SetSize(0);
stmTmp.WriteBuffer(Buffer,length(Buffer));
stmTmp.Seek(0,soFromBeginning);
ini.WriteBinaryStream(Section,format(sKey,),stmTmp);
end;
if stmStr.Size mod BuffSize >0 then
begin
FillChar(Buffer,length(Buffer),#0);
stmStr.Read(Buffer,stmStr.Size mod BuffSize);
stmTmp.SetSize(0);
stmTmp.WriteBuffer(Buffer,stmStr.Size mod BuffSize);
stmTmp.Seek(0,soFromBeginning);
ini.WriteBinaryStream(Section,format(sKey,),stmTmp);
end;
finally
stmTmp.Free;
end;
finally
stmStr.Free;
end;
finally
ini.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToStream }
{ 说明: 保存到流 }
{ 日期: 2006.01.07 }
{ 参数: Stream: TStringStream }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.SaveToStream(Stream: TStringStream);
var
ssAll,ss:TStrings;
i:integer;
begin
if FDataSet=nil then exit;
ss:=TStringlist.Create;
ssAll:=TStringlist.Create;
try
for i:=0 to FDataSet.Fields.Count-1 do
begin
ss.Text:= ComponentToString(FDataSet.Fields);
ssAll.AddStrings(ss);
end;
if ssAll.Count>0 then
begin
Stream.Size:=0;
Stream.writeString(ssAll.Text);
end;
finally
ssAll.Free;
ss.Free;
end;
end;
initialization
RegisterClasses([TIntegerField,TBooleanField,TDateTimeField,TFloatField,
TCurrencyField,TWideStringField,TBlobField,TDataSetField,TDateField,TMemoField,
TWordField,TStringField,TAutoIncField,TSmallintField,TTimeField,TBCDField]);
end.
code:
{******************************************************************************}
{* }
{* 单元名称:读写TDataSet的Fields对象 }
{* 创建日期:2006.01.07 }
{* 单元作者:cgs }
{* 备 注: }
{* 开发平台:PWin2000pro + Delphi 7.0 }
{* 版权所有 (C) 2006 cgs_studio }
{* 更新记录: }
{* }
{******************************************************************************}
unit uCKFields;
interface
uses
Classes, sysutils, DB;
type
TCKFields = class(TObject)
private
FDataSet: TDataSet;
function GetFields: TFields;
function GetField(index: integer): TField;
public
constructor Create(ds: TDataSet);
procedure SaveToFile(FileName:string);
procedure LoadFromFile(FileName:string);
procedure SaveToStream(Stream:TStringStream);
procedure LoadFromStream(Stream:TStringStream);
procedure SaveToIni(iniFileName,Section:string);
procedure LoadFromIni(iniFileName,Section:string);
property DataSet:TDataSet read FDataSet;
property Fields:TFields read GetFields;
property Items[index:integer]:TField read GetField; Default;
end;
function ComponentToString(Component: TComponent): string;
function StringToComponent(Value: string): TComponent;
implementation
uses strutils ,inifiles;
function ComponentToString(Component: TComponent): string;
var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(Component);
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStream, StrStream);
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free;
end;
finally
BinStream.Free
end;
end;
function StringToComponent(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value);
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStream, BinStream);
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(nil);
finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;
{ TCKFields }
constructor TCKFields.Create(ds: TDataSet);
begin
inherited Create;
FDataSet:=ds;
end;
function TCKFields.GetField(index: integer): TField;
begin
result:=nil;
if FDataSet<>nil then
result:=FDataSet.Fields[index];
end;
function TCKFields.GetFields: TFields;
begin
result:=nil;
if FDataSet<>nil then
result:=FDataSet.Fields;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromFile }
{ 说明: 从文本文件中读取读取Fields }
{ 日期: 2006.01.07 }
{ 参数: FileName: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.LoadFromFile(FileName: string);
var
ssFile:TStrings;
stmStr:TStringStream;
begin
if FDataSet=nil then exit;
ssFile:=TStringlist.Create;
try
ssFile.LoadFromFile(FileName);
if ssFile.Count=0 then exit;
stmStr:=TStringStream.Create(ssFile.Text);
try
LoadFromStream(stmStr);
finally
stmStr.Free;
end;
finally
ssFile.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromIni }
{ 说明: 从INI文本文件中读取读取Fields }
{ 日期: 2006.01.07 }
{ 参数: iniFileName, Section: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.LoadFromIni(iniFileName, Section: string);
const
sKey= 'CKFields%d';
var
i:integer;
ini:TInifile;
stmStr:TStringStream;
stmTmp:TMemoryStream;
begin
ini:=TInifile.Create(iniFileName);
try
stmStr:= TStringStream.Create('');
try
stmTmp:=TMemoryStream.Create;
try
stmStr.Seek(0,soFromBeginning);
i:=0;
while true do
begin
stmTmp.SetSize(0);
ini.ReadBinaryStream(Section,format(sKey,),stmTmp);
if stmTmp.Size =0 then break;
stmTmp.Seek(0,soFromBeginning);
stmStr.CopyFrom(stmTmp,stmTmp.Size);
inc(i);
end;
LoadFromStream(stmStr);
finally
stmTmp.Free;
end;
finally
stmStr.Free;
end;
finally
ini.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromStream }
{ 说明: 从流中读取Fields }
{ 日期: 2006.01.07 }
{ 参数: Stream: TStringStream }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.LoadFromStream(Stream: TStringStream);
var
ssAll,ss:TStrings;
i:integer;
Component:TComponent;
begin
if FDataSet=nil then exit;
ss:=TStringlist.Create;
ssAll:=TStringlist.Create;
try
ssAll.Text:=Stream.DataString;
if ssAll.Count=0 then exit;
FDataSet.Fields.Clear;
for i:=0 to ssAll.Count-1 do
begin
if LowerCase(LeftStr(ssAll,6))='object' then
begin
ss.Clear;
ss.Add(ssAll);
end
else if LowerCase(LeftStr(ssAll,3))='end' then
begin
ss.Add(ssAll);
Component:= StringToComponent(ss.Text);
FDataSet.Fields.Add(TField(Component));
end
else if trim(ssAll)='' then
begin
break;
end
else
ss.Add(ssAll);
end;
finally
ssAll.Free;
ss.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToFile }
{ 说明: 保存到文本文件 }
{ 日期: 2006.01.07 }
{ 参数: FileName: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.SaveToFile(FileName: string);
var
ssFile:TStrings;
stmStr:TStringStream;
begin
if FDataSet=nil then exit;
ssFile:=TStringlist.Create;
try
stmStr:= TStringStream.Create('');
try
SaveToStream(stmStr);
ssFile.Text:=stmStr.DataString;
ssFile.SaveToFile(FileName);
finally
stmStr.Free;
end;
finally
ssFile.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToIni }
{ 说明: 保存到INI文件 }
{ 日期: 2006.01.07 }
{ 参数: iniFileName, Section: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.SaveToIni(iniFileName, Section: string);
const
BuffSize=40;
sKey= 'CKFields%d';
var
i:integer;
ini:TInifile;
stmStr:TStringStream;
stmTmp:TMemoryStream;
Buffer:Array[0..BuffSize-1] of char;
begin
ini:=TInifile.Create(iniFileName);
try
ini.EraseSection(Section);
stmStr:= TStringStream.Create('');
try
stmTmp:=TMemoryStream.Create;
try
SaveToStream(stmStr);
stmStr.Seek(0,soFromBeginning);
for i:=0 to stmstr.Size div BuffSize -1 do
begin
FillChar(Buffer,length(Buffer),#0);
stmStr.Read(Buffer,length(Buffer));
stmTmp.SetSize(0);
stmTmp.WriteBuffer(Buffer,length(Buffer));
stmTmp.Seek(0,soFromBeginning);
ini.WriteBinaryStream(Section,format(sKey,),stmTmp);
end;
if stmStr.Size mod BuffSize >0 then
begin
FillChar(Buffer,length(Buffer),#0);
stmStr.Read(Buffer,stmStr.Size mod BuffSize);
stmTmp.SetSize(0);
stmTmp.WriteBuffer(Buffer,stmStr.Size mod BuffSize);
stmTmp.Seek(0,soFromBeginning);
ini.WriteBinaryStream(Section,format(sKey,),stmTmp);
end;
finally
stmTmp.Free;
end;
finally
stmStr.Free;
end;
finally
ini.Free;
end;
end;
{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToStream }
{ 说明: 保存到流 }
{ 日期: 2006.01.07 }
{ 参数: Stream: TStringStream }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.SaveToStream(Stream: TStringStream);
var
ssAll,ss:TStrings;
i:integer;
begin
if FDataSet=nil then exit;
ss:=TStringlist.Create;
ssAll:=TStringlist.Create;
try
for i:=0 to FDataSet.Fields.Count-1 do
begin
ss.Text:= ComponentToString(FDataSet.Fields);
ssAll.AddStrings(ss);
end;
if ssAll.Count>0 then
begin
Stream.Size:=0;
Stream.writeString(ssAll.Text);
end;
finally
ssAll.Free;
ss.Free;
end;
end;
initialization
RegisterClasses([TIntegerField,TBooleanField,TDateTimeField,TFloatField,
TCurrencyField,TWideStringField,TBlobField,TDataSetField,TDateField,TMemoField,
TWordField,TStringField,TAutoIncField,TSmallintField,TTimeField,TBCDField]);
end.