http://www.360doc.com/content/16/1128/19/28222077_610249962.shtml

利用Delphi的File Of Type创建并管理属于你自己的数据库

2016-11-28  疯魔狂徒...  转自 aaie_
修改

 

微信分享:

 

前言

  在程序中,我们需要用一个途径去把一些有规律的信息存储在磁盘上。不能用TXT格式的文件──因为它不是基于“记录”的,而且管理很不方便。
  BDE或ADO也就是说Paradox、Access……唉,不列举了──这些我都不想用,尤其不想用BDE。我要用的是ASCII文本文件。Delphi能做到吗?当然能!这就是“File Of”类型文件,或者说files of some type/binary files。
  (译者注:与所有的Win32桌面应用程序编译器相比,Delphi有一个很独到的特点:它编译的Exe可以不需要一些公共动态链接库的支持,尽管因此Delphi的EXE文件可能大一点。而VC、C++Builder、VFP等等这些我用过的编译器,却不是这样,它们编译的EXE往往需要打包一些Dll才可以用。那么,我们用Delphi开发数据库程序时,使用BDE、ADO等等引擎,却因此给Delphi蒙羞──BDE、ADO等等,一般都需要单独安装到操作系统中去。)
  下面举例演示这个应用。

首先

  我们首先要定义一个基类,也就是一个记录结构:

type
   TMember = record
     Name : string[10];
     eMail : string[20];
     Posts : LongInt;
   end;

  然后声明一个记录集,假设有5条记录:
var Members : array[1..5] of TMember; 
  在我们读写我们的数据信息前,我们需要声明一个基于我们记录结构的文件变量:
var F : file of TMember; 
  注:在Delphi里,我们声明一个文件变量的一般格式就是:
var SomeTypedFile : file of SomeType;
  这里所说的基类(Some Type),比如可以是Double、数组、记录。但不能是长字符串格式、动态数组、类类型以及指针。
  接下来我们要把我们的“数据库”文件链接到我们的程序里去:
AssignFile(F, 'Members.dat') ;
  使用一个“文件”,我们需要这样“打开”它,并调用Reset方法打开一个已存在于硬盘上的文件,用Rewrite方法去创建一个新文件。当文件使用完毕,关闭应用程序之前,我们要记得用CloseFile方法“关闭”它。如果忘记关闭,将引起一个I/O错误。当文件句柄被关闭,此前对它的所有更新操作将应用。
  (译者注:上面所说的“文件”,不仅仅包括磁盘文件,而且包括串口、打印机、其他设备……这些都是“文件”。)

写入到文件

  假设我们已经填充了Members里的5条记录。那么,接下来就是把这5条记录写入磁盘文件的代码:
var
   F : file of TMember;
   i : integer;
begin
AssignFile(F,'members.dat') ;
Rewrite(F) ;
try
   for i:= 1 to 5 do
    Write (F, Members[i]) ;
finally
   CloseFile(F) ;
end;
end;

从磁盘文件读出所有记录

var
   Member: Tmember;
   F : file of TMember;
begin
AssignFile(F,'members.dat') ;
Reset(F) ;
try
   while not Eof(F) do begin
    Read (F, Member) ;
    {DoSomethingWithMember;}
   end;
finally
   CloseFile(F) ;
end;
end; 
  注:EOF是文件的结束标志。我们通过判断它的真假,来知道哪里是文件里最后的一条记录。

Seeking and Positioning

  文件记录通常是要不断更新的。在一般情况下,我们读写一条记录后,游标立即指向下一条记录。我们可以用下面的方法实现在记录间自由移动游标:

{ 回到文件头,即第1条记录 }
Seek(F, 0) ;

{ 跳到第3条记录 }
Seek(F, 3) ;

{ 跳到文件尾,即最后一条记录的后面 }
Seek(F, FileSize(F)) ;

记录的更新

  前面我们仅仅学习了如何读写记录。那么如果我们要求找到第10条记录,然后把这条记录的某个字段(如:Email)修改一下,怎么做?请看下面的代码:

procedure ChangeEMail(const RecN : integer; const NewEMail : string) ;
var DummyMember : TMember;
begin
{ assign, open, exception handling 模块略 }
Seek(F, RecN) ;
Read(F, DummyMember) ;
DummyMember.Email := NewEMail;
{ 此时游标已下移,我们需要重新返回游标位置 }
Seek(F, RecN) ;
Write(F, DummyMember) ;
{ 关闭文件 }
end;

结束语
  至此,我们已经知道如何写记录到磁盘文件,如何读取,如何仅仅改变文件中间某条记录的一部分数据。

附:一个完整的例子代码

  (译者注:这个完整的例子代码是由译者附加的,在Delphi6 + Windows2000上编译通过。因时间紧,没有写“添加”“删除”一条记录的代码。基于本文及本例,读者完全可以写一个控件,完成象BDE、ADO那样的功能。)

unit Unt_Main;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls;

type
   TFrm_Main = class(TForm)
     Btn_FillDemoData: TButton;
     Btn_ReadAll: TButton;
     Edt_Name: TEdit;
     Edt_Email: TEdit;
     Edt_Posts: TEdit;
     Btn_GoFirst: TButton;
     Btn_Go4th: TButton;
     Btn_GoLastRecord: TButton;
     Btn_ReWriteNowRec: TButton;
     Btn_Next: TButton;
     Btn_Previous: TButton;
     procedure Btn_FillDemoDataClick(Sender: TObject);
     procedure Btn_ReadAllClick(Sender: TObject);
     procedure Btn_GoFirstClick(Sender: TObject);
     procedure Btn_Go4thClick(Sender: TObject);
     procedure Btn_GoLastRecordClick(Sender: TObject);
     procedure Btn_NextClick(Sender: TObject);
     procedure Btn_PreviousClick(Sender: TObject);
     procedure Btn_ReWriteNowRecClick(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;

var
   Frm_Main: TFrm_Main;

implementation

{$R *.dfm}

type
   TMember = record
     Name : string[10];
     eMail : string[20];
     Posts : LongInt;
   end;

const
   DBFname : string = 'c:\members.dat';
var
   Members : array[1..5] of TMember;
   aMember : TMember;
   nowRecNo: integer = -1;

procedure MembersInit;
begin
   Members[1].Name := 'TheFirst';
   Members[1].eMail:= '1bcdefgh@163.com';
   Members[1].Posts:= 262201;
   Members[2].Name := 'TheSecond';
   Members[2].eMail:= '2bcdefgh@163.com';
   Members[2].Posts:= 262202;
   Members[3].Name := 'TheThird';
   Members[3].eMail:= '3bcdefgh@163.com';
   Members[3].Posts:= 262203;
   Members[4].Name := 'The4th';
   Members[4].eMail:= '4bcdefgh@163.com';
   Members[4].Posts:= 262204;
   Members[5].Name := 'The5th';
   Members[5].eMail:= '5bcdefgh@163.com';
   Members[5].Posts:= 262205;
end;

function SeekRec(RecNo : integer; var aMember : TMember):boolean;
var
   F : file of TMember;
begin
   AssignFile(F,DBFname) ;
   Reset(F) ;
   try
     Seek(F,RecNo-1);
     Read (F, aMember);
     Result := True;
   Except
     Result := False;
   end;
   CloseFile(F);
end;

function UpdateRec(RecNo : integer; var aMember : TMember):boolean;
var
   F : file of TMember;
begin
   AssignFile(F,DBFname) ;
   Reset(F) ;
   try
     Seek(F,RecNo-1);
     Write(F, aMember);
     Result := True;
   Except
     Result := False;
   end;
   CloseFile(F);
end;

procedure TFrm_Main.Btn_FillDemoDataClick(Sender: TObject);
var
   F : file of TMember;
   i : integer;
begin
   MembersInit;
   AssignFile(F,DBFname) ;
   Rewrite(F) ;
   try
     for i:= Low(Members) to High(Members) do
         Write (F, Members[i]) ;
   finally
     CloseFile(F) ;
   end;
end;

procedure TFrm_Main.Btn_ReadAllClick(Sender: TObject);
var
   Member: TMember;
   F : file of TMember;
begin
   AssignFile(F,DBFname) ;
   Reset(F) ;
   try
     while not Eof(F) do begin
        Read (F, Member) ;
       {DoSomethingWithMember;}
     end;
   finally
     CloseFile(F) ;
   end;
end;

procedure TFrm_Main.Btn_GoFirstClick(Sender: TObject);
begin
   nowRecNo := 1;
   if SeekRec(nowRecNo,aMember) then
      begin
      Edt_Name.Text := aMember.Name;
      Edt_Email.Text:= aMember.eMail;
      Edt_Posts.Text:= IntToStr(aMember.Posts);
      end
      else showmessage('Error');
end;

procedure TFrm_Main.Btn_Go4thClick(Sender: TObject);
begin
   nowRecNo := 4;
   if SeekRec(nowRecNo,aMember) then
      begin
      Edt_Name.Text := aMember.Name;
      Edt_Email.Text:= aMember.eMail;
      Edt_Posts.Text:= IntToStr(aMember.Posts);
      end
      else showmessage('Error');
end;

procedure TFrm_Main.Btn_GoLastRecordClick(Sender: TObject);
{ Or Use SeekRec(5,aMember) }
var
   F : file of TMember;
begin
   AssignFile(F,DBFname) ;
   Reset(F) ;
   nowRecNo := FileSize(F);
   try
     Seek(F,nowRecNo-1);
     Read (F, aMember);
     Edt_Name.Text := aMember.Name;
     Edt_Email.Text:= aMember.eMail;
     Edt_Posts.Text:= IntToStr(aMember.Posts);
   Except
     showmessage('Error');
   end;
   CloseFile(F);
end;

procedure TFrm_Main.Btn_NextClick(Sender: TObject);
begin
   nowRecNo := nowRecNo + 1;
   if SeekRec(nowRecNo,aMember) then
      begin
      Edt_Name.Text := aMember.Name;
      Edt_Email.Text:= aMember.eMail;
      Edt_Posts.Text:= IntToStr(aMember.Posts);
      end
      else showmessage('Error');
end;

procedure TFrm_Main.Btn_PreviousClick(Sender: TObject);
begin
   nowRecNo := nowRecNo - 1;
   if SeekRec(nowRecNo,aMember) then
      begin
      Edt_Name.Text := aMember.Name;
      Edt_Email.Text:= aMember.eMail;
      Edt_Posts.Text:= IntToStr(aMember.Posts);
      end
      else showmessage('Error');
end;

procedure TFrm_Main.Btn_ReWriteNowRecClick(Sender: TObject);
begin
   aMember.Name := Edt_Name.Text;
   aMember.eMail:= Edt_Email.Text;
   aMember.Posts:= StrToInt(Trim(Edt_Posts.Text));
   if not UpdateRec(nowRecNo,aMember) then
      showmessage('Error');
end;

end.

利用Delphi的File Of Type创建并管理属于你自己的数据库的更多相关文章

  1. 利用Delphi监视注册表的变化

    转帖:利用Delphi监视注册表的变化 2009-12-23 11:53:51 分类: 利用Delphi监视注册表的变化       我们在编写软件的时候,常常需要把一些信息保存到系统的注册表中.如果 ...

  2. 利用Delphi编写IE扩展

    就是如何使IE扩展组件可以响应事件.    在自己的程序中使用过WebBrowser控件的朋友都知道,WebBrowser控件定义了诸如BeforeNavigate.DownloadComplete ...

  3. python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))

    昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...

  4. 利用sublime的snippet功能快速创建代码段

    在前端开发中我们经常会输入相同的一些基本代码,例如常用的jquery引用,bootstrap框架,cssreset等等,如果每次使用时在复制粘贴感觉很麻烦,这里介绍一种更为简洁的方法 利用sublim ...

  5. JAVA之旅(二十八)——File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤

    JAVA之旅(二十八)--File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤 我们可以继续了,今天说下File 一.File概述 文件的操作是非常 ...

  6. 利用开机账户登录“轻松访问”创建Windows后门

    利用开机账户登录“轻松访问”创建Windows后门 实验原理: 利用登录账户界面的“轻松访问”中的“放大镜”,把它替换为cmd.exe程序,实现在不登录的情况下打开命令提示符,并进行一些操作(打开的c ...

  7. 利用Microsoft Sql Server Management studio 创建数据库的示例

    利用Microsoft Sql Server Management studio 创建数据库的示例方法如下:   一.打开安装好的Microsoft Sql Server Management stu ...

  8. 【Unity】3.1 利用内置的3D对象创建三维模型

    分类:Unity.C#.VS2015 创建日期:2016-04-02 一.基本概念 Unity已经内置了一些基本的3D对象,利用这些内置的3D对象就可以直接构建出各种3D模型(当然,复杂的三维模型还需 ...

  9. 利用 Create React Native App 快速创建 React Native 应用

    本文介绍的 Create-React-Native-App 是非常 Awesome 的工具,而其背后的 Expo 整个平台也让笔者感觉非常的不错.笔者目前公司是采用 APICloud 进行移动应用开发 ...

随机推荐

  1. Couldn't open file on client side, trying server side 错误解决

    09-09 09:43:21.651: D/MediaPlayer(3340): Couldn't open file on client side, trying server side09-09 ...

  2. MongoDB学习笔记二:创建、更新及删除文档

    插入并保存文档 对目标集使用insert方法插入一个文档: > db.foo.insert({"bar" : "baz"}) 这个操作会给文档增加一个&q ...

  3. sublimetext 使用正则表达式匹配中文

    [\x{4e00}-\x{9fa5}] ============================================= 参考资料 1.在javascript下正确的\x4e00-\x9fa ...

  4. phpstorm8.0汉化版下载

    下载地址http://www.52z.com/soft/161911.html 汉化包:http://www.7down.net/soft/20586.html phpStorm汉化方法 1.安装原版 ...

  5. 【freemaker】之自定义指令<#macro>

    测试代码 @Test public void test07(){ try { root.put("name", "张三"); freemakerUtil.fpr ...

  6. 关于block的一些理解

    之前一直都是用这别人或者是系统系统封装好的block,用这都挺好,可以访问那些定义了block变量的函数变量在block中使用. 首先总结一个block的用法:1.block有些类似于函数的指针 拥有 ...

  7. [HTML] CSS Id 和 Class选择器

    id 和 class 选择器 如果你要在HTML元素中设置CSS样式,你需要在元素中设置"id" 和 "class"选择器. id 选择器 id 选择器可以为标 ...

  8. JAVA设计模式之迭代子模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述迭代子(Iterator)模式的: 迭代子模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不 ...

  9. floyd

    求任意两点之间的最短路径.e[i][j]为记录从i到j之间的距离,当循环结束后最后存储的就是i到j之间的最短路径啦. floyd算法就是对于给定的n个结点,对于每一个e[i][j],都让它经过1,然后 ...

  10. java 获取classpath下文件多种方式

    java 获取classpath下文件多种方式 一:properties下配置 在resources下定义server.properties register.jks.path=classpath\: ...