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. RestTemplate 请求url

    1.get 请求 RestTemplate restTemplate = new RestTemplate(); String url = ""; JSONObject resul ...

  2. bootstrap-9

    图像: bootstrap中有以下几种样式风格: 1.img-responsive:响应式图片,主要针对响应式设计 2.img-rounded:圆角图片 3.img-circle:圆形图片 4.img ...

  3. c数据结构栈的基本操作(字符逆序输出)

    线性栈 输入字符,再输出 #include "stdafx.h" #include<stdlib.h> #include<malloc.h> #define ...

  4. LeetCode() Min Stack 不知道哪里不对,留待。

    class MinStack { public: MinStack() { coll.resize(2); } void push(int x) { if(index == coll.size()-1 ...

  5. python requests库入门[转]

    首先,确认一下: Requests 已安装 Requests是 最新的 让我们从一些简单的示例开始吧. 发送请求 使用Requests发送网络请求非常简单. 一开始要导入Requests模块: > ...

  6. RabbitMQ 安装

    Install Erlang from the Erlang Solutions repository or Follow the instructions under "Installat ...

  7. CSS基本知识汇总

    1.CSS 简介 CSS 指层叠样式表 (Cascading Style Sheets),是一种用来表现 HTML 文档样式的语言,样式定义如何显示 HTML 元素,是能够真正做到网页表现与结构分离的 ...

  8. linux查看磁盘io的几种方法

    怎样才能快速的定位到并发高是由于磁盘io开销大呢?可以通过三种方式: 第一种:用 top 命令 中的cpu 信息观察 Top可以看到的cpu信息有: Tasks: 29 total, 1 runnin ...

  9. 每天一个 Linux 命令(5):rm 命令

    昨天学习了创建文件和目录的命令mkdir ,今天学习一下linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所 ...

  10. FW开发代码规范---小任性(1)

    ---恢复内容开始--- 使代码容易理解的方法无非是准确地注释和增强代码一致性. 一个好的准确的注释让代码容易理解是显然的.而代码的一致性,使编程风格统一,容易在内部形成一些共识.习惯用语和模式. 一 ...