首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
首页 | JAVA | C# | VB | VB.NET | C/C++ | delphi | 工程管理 | 其他语言 | 论坛
各大城市软件开发培训、软件人才免费咨询热线:400-700-5807
 您现在的位置: 中国IT实验室 >> 桌面开发 >> Delphi >> 正文
用Delphi编写数据报存储控件
来源:ChinaItLab 作者:佚名 时间:2007-4-5

  一、概述
  
  在用Delphi编写数据库程序时,经常涉及到数据的导入和导出操作,如:将大型数据库中的数据存储为便携文件,以便于出外阅读;将存储在文件中的数据信息,导入到另外的数据库中;而且,通过将数据库中的数据存储为数据文件,更便于程序内部和程序间交换数据,避免通过内存交换数据的烦琐步骤,例如在笔者编写的通用报表程序中即以该控件作为数据信息传递的载体。
  
  二、基本思路
  
  作为数据报存储控件,应能够存储和读入数据集的基本信息(如:字段名,字段的显示名称,字段的数据类型,记录数,字段数,指定记录指定字段的当前值等),应能够提供较好的封装特性,以便于使用。
  基于此,笔者利用Delphi5.0面向对象的特点,设计开发了数据报存储控件。
  
  三、实现方法
  
  编写如下代码单元:
  unit IbDbFile;
  interface
  Uses Windows, SysUtils, Classes, Forms, Db, DbTables, Dialogs;
  Const
  Flag = '数据报-吉星软件工作室';
  Type
  TDsException = Class(Exception);
  TIbStorage = class(TComponent)
  private
  FRptTitle: string; //存储数据报说明
  FPageHead: string; //页头说明
  FPageFoot: string; //爷脚说明
  FFieldNames: TStrings; //字段名表
  FStreamIndex: TStrings; //字段索引
  FStream: TStream; //存储字段内容的流
  FFieldCount: Integer; //字段数
  FRecordCount: Integer; //记录数
  FOpenFlag: Boolean; //流是否创建标志
  protected
  procedure Reset; //复位---清空流的内容
  procedure SaveHead(ADataSet: TDataSet; Fp: TStream); //存储报表头信息
  procedure LoadTableToStream(ADataSet: TDataSet); //存储记录数据
  procedure IndexFields(ADataSet: TDataSet); //将数据集的字段名保存到列表中
  procedure GetHead(Fp: TFileStream); //保存报表头信息
  procedure GetIndex(Fp: TFileStream); //建立记录流索引
  procedure GetFieldNames(Fp: TFileStream); //从流中读入字段名表
  function GetFieldName(AIndex: Integer): string; //取得字段名称
  function GetFieldDataType(AIndex: Integer): TFieldType;
  function GetDisplayLabel(AIndex: Integer): string; //取得字段显示名称
  procedure SaveFieldToStream(AStream: TStream; AField: TField); //将字段存入流中
  function GetFieldValue(ARecordNo, FieldNo: Integer): string; //字段的内容
  public
  Constructor Create(AOwner: TComponent);
  Destructor Destroy; override;
  procedure Open; //创建流以准备存储数据
  procedure SaveToFile(ADataSet: TDataSet; AFileName: string); //存储方法
  procedure LoadFromFile(AFileName: string); //装入数据
  procedure FieldStream(ARecordNo, FieldNo: Integer; var AStream: TStream);
  property FieldNames[Index: Integer]: string read GetFieldName; //字段名
  property FieldDataTypes[Index: Integer]: TFieldType read GetFieldDataType;
  property FieldDisplayLabels[Index: Integer]: string read GetDisplayLabel;
  property Fields[RecNo, FieldIndex: Integer]: string read GetFieldValue;
  //property FieldStreams[RecNo, FieldIndex: Integer]: TStream read GetFieldStream;
  property RecordCount: Integer read FRecordCount write FRecordCount;
  property FieldCount: Integer read FFieldCount write FFieldCount;
  published
  property RptTitle: string read FRptTitle write FRptTitle;
  property PageHead: string read FPageHead write FPageHead;
  property PageFoot: string read FPageFoot write FPageFoot;
  end;
  
  function ReadAChar(AStream: TStream): Char;
  function ReadAStr(AStream: TStream): string;
  function ReadBStr(AStream: TStream; Size: Integer): string;
  function ReadAInteger(AStream: TStream): Integer;
  procedure WriteAStr(AStream: TStream; AStr: string);
  procedure WriteBStr(AStream: TStream; AStr: string);
  procedure WriteAInteger(AStream: TStream; AInteger: Integer);
  
  procedure Register;
  implementation
  
  procedure Register;
  begin
  RegisterComponents('Data Access', [TIbStorage]);
  end;
  
  function ReadAChar(AStream: TStream): Char;
  Var
  AChar: Char;
  begin
  AStream.Read(AChar, 1);
  Result := AChar;
  end;
  
  function ReadAStr(AStream: TStream): string;
  var
  Str: String;
  C : Char;
  begin
  Str := '';
  C := ReadAChar(AStream);
  While C <> #0 do
  begin
  Str := Str + C;
  C := ReadAChar(AStream);
  end;
  Result := Str;
  end;
  
  function ReadBStr(AStream: TStream; Size: Integer): string;
  var
  Str: String;
  C : Char;
  I : Integer;
  begin
  Str := '';
  For I := 1 to Size do
  begin
  C := ReadAChar(AStream);
  Str := Str + C;
  end;
  Result := Str;
  end;
  
  function ReadAInteger(AStream: TStream): Integer;
  var
  Str: String;
  C : Char;
  begin
  Result := MaxInt;
  Str := '';
  C := ReadAChar(AStream);
  While C <> #0 do
  begin
  Str := Str + C;
  C := ReadAChar(AStream);
  end;
  try
  Result := StrToInt(Str);
  except
  Application.MessageBox(' 当前字符串无法转换为整数!', '错误',
  Mb_Ok + Mb_IconError);
  end;
  end;
  
  
  procedure WriteAStr(AStream: TStream; AStr: string);
  begin
  AStream.Write(Pointer(AStr)^, Length(AStr) + 1);
  end;
  
  procedure WriteBStr(AStream: TStream; AStr: string);
  begin
  AStream.Write(Pointer(AStr)^, Length(AStr));
  end;
  
  procedure WriteAInteger(AStream: TStream; AInteger: Integer);
  var
  S : string;
  begin
  S := IntToStr(AInteger);
  WriteAstr(AStream, S);
  end;
  
  Constructor TIbStorage.Create(AOwner: TComponent);
  begin
  inherited Create(AOwner);
  FOpenFlag := False; //确定流是否创建的标志
  end;
  
  Destructor TIbStorage.Destroy;
  begin
  if FOpenFlag then
  begin
  FStream.Free;
  FStreamIndex.Free;
  FFieldNames.Free;
  end;
  inherited Destroy;
  end;
  
  procedure TIbStorage.Open;
  begin
  FOpenFlag := True;
  FStream := TMemoryStream.Create;
  FStreamIndex := TStringList.Create;
  FFieldNames := TStringList.Create;
  Reset;
  end;
  
  procedure TIbStorage.Reset; //复位
  begin
  if FOpenFlag then
  begin
  FFieldNames.Clear;
  FStreamIndex.Clear;
  FStream.Size := 0;
  FRptTitle := '';
  FPageHead := '';
  FPageFoot := '';
  FFieldCount := 0;
  FRecordCount := 0;
  end;
  end;
  
  //-------保存数据部分
  procedure TIbStorage.SaveToFile(ADataSet: TDataSet; AFileName: string);
  var
  Fp: TFileStream;
  I : Integer;
  Ch: Char;
  T1, T2: TDateTime;
  Str: string;
  begin
  if Not FOpenFlag then
  begin
  showmessage(' 对象没有打开');
  Exit;
  end;
  try
  if FileExists(AFileName) then DeleteFile(AFileName);
  Fp := TFileStream.Create(AFileName, fmCreate);
  Reset;
  SaveHead(ADataSet, Fp); //保存头部信息---附加说明
  IndexFields(ADataSet); //将数据集的字段信息保存到FFieldName
  LoadTableToStream(ADataSet); //保存数据集的数据信息
  WriteAStr(Fp, FFieldNames.Text); //存储字段名信息
  Ch := '@';
  Fp.Write(Ch, 1);
  WriteAStr(Fp, FStreamIndex.Text); //存储字段索引列表
  Ch := '@';
  Fp.Write(Ch, 1);
  Fp.CopyFrom(FStream, 0);
  finally
  Fp.Free;
  end;
  end;
  
  procedure TIbStorage.SaveHead(ADataSet: TDataSet; Fp: TStream);
  Var
  I : Integer;
  Ch: Char;
  begin
  if Not ADataSet.Active then ADataSet.Active := True;
  WriteAStr(Fp, Flag);
  WriteAStr(Fp, FRptTitle);
  WriteAStr(Fp, FPageHead);
  WriteAStr(Fp, FPag
【责编:Lili】
中国IT教育热线咨询
相关文章
Delphi初学者应小心的六大陷阱
基于Delphi的异常处理技术探究
Delphi中用API实现在MSN的信息提示
编写快速高效的VB程序
Delphi中"包"的妙用…
如何用Delphi实现子目录级的文件查询
在Delphi数据库应用程序中常见错误
如何使用Delphi实现无边界窗体的移动
如何用Delphi创建快捷方式
利用 Delphi 轻松编制压缩助理程序…
推荐文章

 精彩友情推荐
·Asp源码 PHP源码
·CGI源码 JSP源码
·建站书籍教程
·服务器软件 .net源码
·建站工具软件
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
最新更新 推荐文章
·框架:J2EE WEB应用架构分析…03-13
·几种VC++数据库开发技术的相对比…03-13
·利用C#实现标注式消息提示窗口03-13
·用C#创建COM对象03-13
·Visual C#多线程参数传递浅析…03-13
·Visual C#多线程参数传递浅析…03-13
·基于HOOK和MMF的Win密码渗透技术11-15
·Visual C++设计超强仿QQ自动伸缩…11-15
·Java SE 6.0实现高质量桌面集成开…11-15
·史玉柱东山再起幕后高人11-15
·用C#创建COM对象09-06
·IT管理十大失误及其对策08-30
·VC中利用MFC设计绘图程序初步08-23
·JAVA中对象创建和初始化过程08-23
·C语言中的位域的使用08-09
·浅谈Java桌面应用程序开发08-09
·C#的前途如何?08-02
·几种VC++数据库开发技术的相对比较07-12
·用Visual C#实现网络封包监视…07-12
·VB.NET中的TextBox控件详解07-12
·VB.NET实现PC与掌上电脑PPC的双向通信07-05