文件与目录的专题

文件管理包括:文件操作、目录操作和驱动器操作3 部分。

文件操作所用到的函数与方法

  1:AssignFile方法

      将一个外部文件的文件名与一个File 类型的变量关联,对File 类型的变量进行初始化

  2:Append 方法

     在文件结尾处增加一行内容

  3:CloseFile方法

     用来关闭文件,同时将文件记录盘上的文件与相关文件变量断开联系。

示例:

Var

    F:TextFile;

begin

   if OpenDialog1.Execute then

   begin

   AssignFile(F,OpenDialog1.FileName);

   Append(F);

   Writeln(F,’写入一行内容’);

   CloseFile(F);

   end;

end;

4:DeleteFile 函数

  将一个文件从记录盘上删除,如果文件不存在或无法删除,则返回False。

    if OpenDialog1.Execute then

    if DeleteFile(OpenDialog1.FileName) then

    ShowMessage(’删除文件成功’)

    else

   ShowMessage(’删除文件失败’);

 

5:Eof 函数  与 Eoln 函数

   判断是否到了文件的结尾。如果文件为空或当前位置在最后一个字符之后,则返回True;

   否则,返回False

   Eoln 函数测试文件指针是否指向一行的最后,适用于文本文件。如果当前的位置在一行的末尾或

   Eof(F)函数返回的是True,则Eoln 函数返回的是True;否则,返回False。

 

6: Erase 过程

     Erase 过程用于删除一个已经存在的文件。如果文件被打开,先关闭该文件再执行删除操作。过程

     原型如下:

      procedure Erase(var F);

 

7:FileExists 函数

    用于测试指定文件名的文件是否存在。如果文件存在,返回True;否则,返回False。

    函数原型如下:

    function FileExists(const FileName: string): Boolean;

8:FileGetAttr 函数

    用于获取一个文件的属性设置。函数原型如下:

    function FileGetAttr(const FileName: string): Integer;

   返回的结果有:

    FaReadOnly  1 只读文件

    FaHidden  2 隐藏文件

    FaSysFile 4 系统文件

    FaVolumeID  8 卷标志文件

    FaDirectory  16 目录文件

    FaArchive  32 存档文件

    FaAnyFile  64 所有类型文件

    如果得到的是33, 说明 即是存档文件 32, 也是只读文件,  依此类推

9:Write 过程

    用来向一个文件中添加内容。过程原型如下:

    procedure Write( [var F: Text; ] P1 [ , P2,..., Pn] ); //文本文件

    procedure Write(F, V1,...,Vn); //有类型文件

   在使用Write 过程之前,首先要AssignFile 过程指派给一个外部文件,然后以写文件的方式打开。

   以下代码实现了向一个文件中添加内容的功能。

 

10.Writeln 过程

   Writeln 过程用来向文本文件中添加一行内容,即在写入内容后面有回车换行符。过程原型如下:

   procedure Writeln([ var F: Text; ] P1 [, P2, ...,Pn ] );

   Writeln 过程的应用方法和Write 过程的应用方法一

 

 

无类型文件操作--------------------------

unit Unit1;

  interface

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

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  FileName = 'c:\temp\binary.dat';
var
  F: file;

//用无类型的方式写入一个字节
procedure TForm1.Button1Click(Sender: TObject);
var
  b: Byte;
begin
  AssignFile(F,FileName);
  Rewrite(F,1); //第二个参数表示: 把 1 个字节当作一个写入单位

  b := 65;
  BlockWrite(F,b,1); //写入; 参数2是要写入的内容; 参数3表示写入 1 次.

  CloseFile(F);
//落实 binary.dat 的大小: 1个字节; 内容: A (可用记事本打开)
end;


//用无类型的方式读出一个字节
procedure TForm1.Button2Click(Sender: TObject);
var
  b: Byte;
begin
  AssignFile(F,FileName);
  Reset(F,1); //把 1 个字节当作一个读取单位

  BlockRead(F,b,1); //读取一次; 放入 b
  ShowMessage(Chr(b)); //A

  CloseFile(F);
end;


//写入更多字节
procedure TForm1.Button3Click(Sender: TObject);
var
  buffer: array[0..127] of Byte;
  i: Integer; //储存多个字节, 需要用数组了
begin
  for i := Low(buffer) to High(buffer) do
    buffer[i] := i; //给数组赋值, 注意现在数组大小是 128

  AssignFile(F,FileName);
  Rewrite(F,32); //规定把 32 个字节当作一个读取单位, 注意这个数字和缓冲区大小必须是倍数关系

  BlockWrite(F,buffer,4); //需要写入几次呢? 128/32=4

  CloseFile(F);
//写成的文件肯定是128字节大小, 但用记事本可能看不了, 因为这个二进制不是文本
end;


//读出
procedure TForm1.Button4Click(Sender: TObject);
var
  buffer: array[0..127] of Byte;
  i: Integer;
begin
  AssignFile(F,FileName);
  Reset(F,4); //把 4 字节当作一个读取单位; 为了那个倍数关系, 这里一般是 1

  BlockRead(F,buffer,32); //当然需要 32 次才能读完

  CloseFile(F);

  //怎么显示一下呢? 还是用 Memo 吧; 显示字符? 数字? 还是十六进制吧
  Memo1.Clear;
  for i := Low(buffer) to High(buffer) do
  begin
    Memo1.Lines.Add(IntToHex(buffer[i],1));
  end;
(*显示结果: 0 1 2 3 ... 7D 7E 7F *)

end;


//读写 Char 与实际读写字节
procedure TForm1.Button5Click(Sender: TObject);
var
  cArr1,cArr2: array[0..4] of Char;
  i: Integer;
  num: Integer; //记录实际读写的字节数
begin
  for i := Low(cArr1) to High(cArr1) do
    cArr1[i] := Chr(65+i); //填充 A B C D E

  AssignFile(F,FileName);
  Rewrite(F,1); //建立

  BlockWrite(F,cArr1,Length(cArr1),num); //参数4: num 是实际写入的字节数
  ShowMessage(IntToStr(num)); //5

  Reset(F,1); //重新打开

  BlockRead(F,cArr2,Length(cArr2),num); //参数5: num 是实际读出的字节数
  ShowMessage(IntToStr(num)); //5

  ShowMessage(cArr2); //ABCDE

  CloseFile(F);
end;


//写入长字符串, 读出其十六进制码
procedure TForm1.Button6Click(Sender: TObject);
var
  p: PChar;
  b: Byte;
begin
  p := '万一的 Delphi 博客';

  AssignFile(F,FileName);     //关联文件名
  Rewrite(F,1);               //创建并打开
  BlockWrite(F,p,Length(p));  //写入


  FileMode := fmOpenRead;     //这时可以设文件为只读
  Reset(F,1);                 //为读取打开

  Memo1.Clear;
  while not Eof(F) do
  begin
    BlockRead(F,b,1);
    Memo1.Text := Memo1.Text + IntToHex(b,2) + ' ';
  end;
  //显示结果: 70 F0 45 00 08 F7 12 00 A6 FB 43 00 A0 1A E5 00 FF C5

  CloseFile(F);
end;


//复制个文件
procedure TForm1.Button7Click(Sender: TObject);
var
  FromF,ToF: file;
  NumRead,NumWritten: Integer;
  Buffer: array[1..2048] of Byte;
begin
  AssignFile(FromF, 'c:\temp\test1.dat'); //假定有这个文件
  Reset(FromF, 1);
  AssignFile(ToF, 'c:\temp\test2.dat');
  Rewrite(ToF, 1);

  repeat
    BlockRead(FromF, Buffer, SizeOf(Buffer), NumRead);
    BlockWrite(ToF, Buffer, NumRead, NumWritten);
  until (NumRead = 0) or (NumWritten <> NumRead);
  { NumRead=0 表示读完了; NumWritten <> NumRead 表示磁盘空间不够了 }

  CloseFile(FromF);
  CloseFile(ToF);
end;

end.

--------------------

 

目录的管理

1:ChDir 过程

改变当前的目录。如果在指定路径中包含有驱动器号(盘符),则相应地改变当前的驱动器。

 

2.CreateDir 函数

新建一个目录。如果创建成功,则返回True;否则返回False。函数原型如下:

function CreateDir(const Dir: string): Boolean;

例如要在C 盘根目录下建立一个Tem 目录可以编写如下代码:

如果想在“C:\Acc”目录下建立一个“A”目录,而“C:\Acc”目录不存在,以下的代码将不能创

建“A”目录。

CreateDir(’C:\Acc\A’);

 

3.DirectoryExists 函数

检测指定的目录是否存在。如果存在,函数则返回True;否则,返回False。函数原型如下:

function DirectoryExists(Name: string): Boolean;

如果在参数Name 中指定的不是绝对路径,则使用相对路径,默认在当前目录中进行查询。

 

4.ForceDirectories 函数

创建指定的目录。通常在创建一个目录的时候,其父级目录必须存在。但是使用ForceDirectories

创建目录的时候就没有这个限制,可以将所需的所有目录一次创建。如果创建成功,则函数返回True;

如果有任何一个目录创建失败,则返回False。函数原型如下:

function ForceDirectories(Dir: string): Boolean;

 

5.GetCurrentDir 函数

获取当前目录的绝对路径。函数原型如下

 

6.GetDir 过程

获取指定驱动器中的当前目录。过程原型如下:

参数D 为指定的驱动器。当D 的数值为0 时,表示默认的驱动器;数值为1 时,表示A 驱动器;

数值为3 时,表示C 驱动器,依次类推。如果指定的驱动器不存在,则参数S 的数值设置为当前的目

 

7.MkDir 过程

新建一个目录。过程原型如下:

procedure MkDir(S: string);

MkDir 过程的用法与CreateDir 过程的用法一样,都只能在已经存在的路径下创建一层目录,MkDir

过程在不存在的路径下创建目录时会提示错误,而CreateDir 过程则不提示

 

8.RemoveDir 函数

删除一个存在的目录,目录必须为空(即目录里面不能包含目录或文件)。函数原型如下:

function RemoveDir(const Dir: string): Boolean;

如果删除目录成功,则返回True;否则,返回False

 

9.RmDir 过程

删除一个存在的目录,目录必须为空。过程原型如下:

procedure RmDir(S: string);

如果要删除的目录不为空,或没有此目录,RmDir 过程会提示错误,而RemoveDir 函数则不提示

错误。

 

10.SelectDirectory 函数

通过显示一个对话框来让用户选择一个目录。

注意:在使用前要在Uses 语句中添加包含FileCtrl 的说明。

函数原型如下:

function SelectDirectory(const Caption: string; const Root: WideString;

out Directory: string): Boolean; overload;

function SelectDirectory(var Directory: string; Options: TSelectDirOpts;

HelpCtx: Longint): Boolean; overload;

对于第1 个重载函数,参数Caption 为对话框的标题内容;参数Root 指定一个目录,为进行浏览

的最初目录;选中的目录保存在参数Directory 中。

对于第2 个重载函数,参数Directory 中指定的目录为对话框显示时选中的目录,最后用户选定的

目录也保存在参数Directory 中;参数Options 为一些设置项目的集合,如果为空,则用户通过对话框

只能选择已经存在的目录,没有提供编辑框给用户来输入一个新的目录名。TSelectDirOpts 类型定义

 

如下:

type

TSelectDirOpt = (sdAllowCreate, sdPerformCreate, sdPrompt);

TSelectDirOpts = set of TSelectDirOpt;

具体数值的含义如下。

• sdAllowCreate 对话框中有一个Edit 组件,用户可以输入新的目录名。但是如果要新建该目录,

程序员必须根据获取的文件自己编写代码新建目录。

• sdPerformCreate 对话框中有一个Edit 组件,用户可以输入一个不存在的目录名,对话框将选中

该目录并创建该目录。

• sdPrompt 对话框中有一个Edit 组件,如果用户输入的目录名不存在,则显示一个信息对话框提

示是否创建新目录。如果同时选中的是sdAllowCreate 设置,则程序员必须根据获取的文件自己编写

代码新建目录。

 

 

11.SetCurrentDir 函数

设置系统的当前目录。函数原型如下:

function SetCurrentDir(const Dir: string): Boolean;

如果设置当前目录成功,则返回True;否则返回False。

 

 

驱动器

1.DiskFree 函数

获取指定驱动器中剩余空间的字节数。函数原型如下:

function DiskFree(Drive: Byte): Int64;

 

2.DiskSize 函数

获取指定驱动器容量,单位为字节数。函数原型如下:

function DiskSize(Drive: Byte): Int64;

DiskSize 函数的用法与DiskFree 函数一样,其Drive 参数的取值也相同,将上面代码中的DiskFree

更换为DiskSize 就能够获得C 盘驱动器的容量了。

此外,一些其他的驱动器信息可以通过目录操作函数来获得。

 

文件类型的输入输出

在Delphi 中把文件分为3 种:文本文件、类型文件和无类型文件。文本文件指可以被任意文件编

辑器读取的ASCII 文件。类型文件指包含由程序员定义的数据类型的文件。无类型文件包含了其他所

有的类型,它是对包含任意格式或无格式数据的文件的统称。

 

无类型文件

文本文件和类型文件的字节数可以通过代码得到,但不是所有的文件都能做到,例如RTF 文件。

虽然RTF 文件中也包含文本文件,但是它还有其他的格式属性,所以需要使用识别RTF 格式的编辑

器才可以进行浏览。

无类型文件是由数据块序列组成的,每个数据块为128 字节大小的数据。无类型文件数据的读写

操作可以利用数据块实现。无类型文件的操作步骤与文本文件的操作步骤基本相同,其操作方法也与

前面两种文件的操作方法基本相同,只是调用的函数略有差异。

 

 

目录与驱动器

获取System 目录

获取System 目录只需要用一个Win32 函数就能够实现,此函数为GetSystemDirectory,它的原型

如下:

UINT GetSystemDirectory(

LPTSTR lpBuffer, //变量

UINT

 

procedure TForm1.Button1Click(Sender: TObject);

var

MySysPath:PChar;

begin

GetMem(MySysPath,255);

GetSystemDirectory(MySysPath,255); //取得系统目录

Edit1.Text:=MySysPath;

end;

――――――――――――

获取Windows 目录

要获取Windows 目录的位置可以调用Win32 的GetWindowsDirectory() 。该函数类似于

GetSystemDirectory(),其返回值的含义也与GetSystemDirectory()相同。该函数的用法如下:

procedure TForm1.Button1Click(Sender: TObject);

var

MyWinPath:String;

begin

SetLength(MyWinPath,144);

if GetWindowsDirectory(PChar(MyWinPath),144)<>0 then

begin

SetLength(MyWinPath,Length(PChar(MyWinPath)));

Edit1.Text:=MyWinPath;

end

else

RaiseLastWin32Error;

end;

如果函数调用成功,GetWindowsDirectory()返回目录路径的长度(整数值),否则返回0,表明有

错误产生。这时可以调用RaiseLastWin32Error()来分析产生错误的原因。

 

GetCurrentDirectory

获取当前目录

 

获取可用驱动器信息

驱动器分为多种类型,可以使用GetDriveType 函数来查看,该函数的原型如下:

UINT GetDriveType(LPCTSTR lpRootPathName);

该函数有7 种返回值,每个返回值对应的驱动器类型如下。

• 0:不能判断的驱动器类型。

• 1:根目录不存在。

• DRIVE_REMOVABLE:这是一个可移动驱动器。

• DRIVE_FIXED:这是硬盘驱动器。

• DRIVE_REMOTE:这是一个网络驱动器。

• DRIVE_CDROM:这是一个光盘驱动器。

• DRIVE_RAMDISK:这是一个虚拟硬盘。

驱动器的容量可以用GetDiskFreeSpace 函数来获取,该函数的原型如下: 

 

 

 

posted @ 2010-08-30 22:57  坚持Delphi  阅读(510)  评论(0)    收藏  举报