文件
类型文件
类型文件的声明方式如下:
1 2
| var fileDesc : file of 类型;
|
文件的类型可以是基本类型,也可以是记录等。
文件变量其实只是一个指针,使用前应该使用 AssignFile()
先跟外部的文件名建立关联。
一些操作文件的例程:
- Reset : 打开存在的文件
- ReWrite : 新建并打开文件,如果文件已存在则先删除再新建打开
- Append : 打开文件并以追加模式写
- CloseFile : 关闭文件,断开文件变量与外部文件的联系
- Read : 读文件到参数指定的记录
- Write : 将参数指定的记录写入文件
Read、Write 的用法大致可以参考以下声明:
1 2
| procedure Read(var F: file; v1 [, v2, v3, ... ]); procedure Write(var F: file; v1 [, v2, v3, ... ]);
|
读写文件的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| Type TRec = record ch1:AnsiChar; ch2:AnsiChar; end; var Rec1, Rec2: TRec; n: integer; path: string; F: file of TRec; begin Rec1.ch1 := 'A'; Rec1.ch2 := 'B'; writeln('请输入文件名: '); Readln(path); AssignFile(F, path); if FileExists(path) then Reset(F) else Rewrite(F); for n := 1 to 9 do Write(F, Rec1); Rec2.ch1 := '-'; Rec2.ch2 := '-'; Write(F,Rec2); CloseFile(F); writeln('文件操作完毕'); readln; end.
|
非类型文件
非类型文件就是不指定类型的 file
类型。
非类型文件的声明方式如下:
使用于类型文件的所有例程(过程与函数),都适用于非类型文件。
此外,还有两个函数专用于非类型文件:
1 2
| function BlockRead(var f: File, var buffer, count: LongInt) : LongInt; function BlockWrite(var f: File, var buffer, count: LongInt) : LongInt;
|
上面是 BlockRead
是将 count
个字节读取到 buffer
中,返回实际读取字节数。
BlockWrite
是将 buffer
的 count
个字节写入到文件 ,返回实际写入字节数。
读写文件的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| var sourcename, targetname: string; FSource, FTarget: file; Buf: array[0..1] of AnsiChar; begin try writeln('请分别输入文件名: '); Readln(sourcename); Readln(targetname); AssignFile(FSource, sourcename); AssignFile(FTarget, targetname); Reset(FSource); Rewrite(FTarget); while eof(FSource) = False do begin BlockRead(FSource, Buf, 1); BlockWrite(FTarget, Buf, 1); end; CloseFile(FSource); CloseFile(FTarget); except writeln('error'); end; writeln('文件操作完毕'); readln; end
|
文本文件
文本文件使用 TextFile 声明:
1 2
| var fileDesc: TextFile;
|
适用于类型文件和非类型文件的所有过程、函数,同样也适用于文本文件。此外,有一点差异的是,reset
打开的文本文件为只读文件,rewrite
及 append
打开的文本文件为只写文件。
另外两个例程 WriteLn
和 ReadLn
用于操作文本文件, WriteLn
直接向文本文件中写入一行内容, ReadLn
则直接从文本文件中读取一行内容。
文件流
TStream
所有的流都是基于 TStream 基类,常见的方法如下:
1 2 3 4 5 6 7 8
| function Read(var Buffer; Count: Longint): Longint; virtual; abstract; function Write(const Buffer; Count: Longint): Longint; virtual; abstract; function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual; procedure ReadBuffer(var Buffer; Count: Longint); procedure WriteBuffer(const Buffer; Count: Longint); function CopyFrom(Source: TStream; Count: Int64): Int64; property Position: Int64 read GetPosition write SetPosition; property Size: Int64 read GetSize write SetSize64;
|
- Position 属性标识了读写指针的位置。
- Size 属性则标识了流所占用的内存的大小。
- 当读写指针处于流的末端时,这两个属性值相等。
文件流
文件流 TFileStream 重点成员:
1 2 3 4 5 6 7 8
| TFileStream = class(TStream) ... constructor Create(const AFileName: string; Mode: Word); overload; function Read(var Buffer; Count: Longint): Longint; override; function Write(const Buffer; Count: Longint): Longint; override; function Seek(const Offset: Int64; Origin: TSeekOrigin):Int64; override; ... end;
|
构造函数的 Mode 表示打开模式:
模式 |
表示意思 |
fmCreate |
只写模式,文件不存在则先创建,文件存在则先清空文件的原内容 |
fmOpenRead |
只读模式 |
fmOpenWrite |
以只写方式打开文件,且写入的内容会取代文件原本的内容 |
fmOpenReadWrite |
打开的文件可读也可写 |
以下为共享模式: |
– |
fmShareCompat |
兼容 DOS 的,无用 |
fmShareExclusive |
打开文件并独占文件,其它程序无法访问 |
fmShareDenyWrite |
其它程序只能通过只读方式打开文件 |
fmShareDenyRead |
其它程序只能通过只写方式打开文件 |
fmShareDenyNone |
不对文件作任何限定 |
Seek
的 Offset
参数表示读写指针移动的字节数,从哪里开始移动由 TSeekOrigin
决定。 TSeekOrigin
参数值有三种:
soFromBegining
soFromCurrent
soFromEnd
Offset
的值可以为负数,例如: Seek(-4, soFromEnd)
;
使用举例:
1 2 3
| Stream := TFileStream.Create(target,fmCreate); Stream.Write(pchar(str)^, length(str)); Stream.Free;
|
内存流
文件流 TMemoryStream 重点成员:
1 2 3 4 5 6 7 8 9 10 11 12 13
| TMemoryStream = class(TStream) ... function Write(const Buffer; Count: Longint): Longint; override; function Read(var Buffer; Count: Longint): Longint; override; function Seek(Offset: Longint; Origin: Word): Longint; override; procedure Clear; procedure LoadFromStream(Stream: TStream); procedure LoadFromFile(const FileName: string); procedure SaveToStream(Stream: TStream); procedure SaveToFile(const FileName: string); property Memory: Pointer read FMemory; ... end;
|
Clear
方法用于清空内存流中的所有内容。
Memory
为一个 pointer 类型的指针,指向内存流在内存中的位置
注意:
- 在使用 LoadFromX 时,内存流中原来的内容会被丢弃
- 使用 SaveToX 时文件的原有内容也会被覆盖
使用举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| uses SysUtils, Classes; var source, target: String; o1, o2: TMemoryStream; begin writeln('输入源文件名: '); readln(source); writeln('输入目标文件名: '); readln(target); o1 := TMemoryStream.Create; o1.LoadFromFile(source); o2 := TMemoryStream.Create; o2.LoadFromStream(o1); o1.WriteBuffer(o2.Memory^, o2.Size); o1.SaveToFile(target); FreeAndNil(o1); FreeAndNil(o2); writeln('ok'); readln; end.
|
字符串流
字符串流 TStringStream 继承于内存流,此外,字符串流中需要注意的新方法有:
1 2 3
| function ReadString(Count: Longint): string; procedure WriteString(const AString: string); property DataString: string read FDataString;
|
使用例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var Stream: TStringStream; begin Stream := TStringStream.Create; Stream.WriteString('d'); Stream.WriteString('e'); Stream.WriteString('l'); Stream.WriteString('p'); Stream.WriteString('h'); Stream.WriteString('i'); writeln(Stream.DataString); FreeAndNil(Stream); readln; end.
|
直接操作文件
Delphi 提供了一组 API 可以直接操作文件,不需要文件类型的变量:
1 2 3 4 5 6
| function FileOpen(const FileName: string): Integer; function FileCreate(const FileName: string): Integer; overload; function FileRead(Handle: Integer; var Buffer; Count: Cardinal): Integer; function FileSeek(Handle: Integer; Offset: Int64; Origin: Integer): Integer; function FileWrite(Handle: Integer; const Buffer; Count: Cardinal): Integer; procedure FileClose(Handle: Integer);
|