Delphi基础教程图文版之文件操作 delphi怎么用
liebian365 2024-11-11 14:46 22 浏览 0 评论
无论什么编程语言文件操作这一块的内容都不会缺席,先正式学习之前我们需要先搞清楚几个概念性的东西
- 数据流(Data Stream):数据在数据源和程序(内存)之间传递的过程
- 输入流(Input Stream):数据从数据源到程序(内存)的过程
- 输出流(Output Stream):从程序(内存)到数据源的过程
其实Delphi针对文件操作这块的内容提供了 3 套 API 的支持,
- 对win32API封装的一套(System)
- 类似于C语言风格的API(System.SysUtils)
- 新的 API(System.Classes),貌似是在 FireMonkey 支持多平台以后才出现的(没有官网证据)
在网络上查询的过程中大部分 Delphi 文件操作这块的实现都是利用的 System.SysUtils和 System 单元内的函数
IO的分类
根据数据的流向分为:输入流和输出流,根据数据的类型分为:字节流和字符流。
所以这样就产生了字节、字符输入流和字节、字符输出流
Delphi 支持三种文件类型: 文本文件、记录文件、无类型文件(记录类型和无类型文件都可以看作是字节流)。
Win32API
其实这部分内容我是取自 万一老师的博客,自己稍加整理之后得来的
文本文件是以行为单位进行读、写的。由于每一行的长度不一定相同,不能计算出给定行在文件中的确切位置,因而只能顺序地读写。
-文本文件只能单独为读或写而打开,在一个打开的文本文件上同时进行读、写操作是不允许的。
文本文件的打开需要 3 个步骤:
- 文件变量与文件名关联:AssignFile(VarTxt, FileName),FileName 如果省略路径将默认当前目录。
- 初始化读写。
(1) Reset: 只读打开, 指针移到文件头;
(2) Rewrite: 创建新文件并打开, 只写;
(3) Append: 从尾部追加, 指针当然在文件尾。
- 释放读写文件:这一步千万不能忘记
案例代码
以下是我整理的代码,在DelphiXE10.4.2测试通过,理论上这种玩法通杀所有版本
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
{ 待读写的结构体 }
TPersonRec = packed record
name: string[12];
age: Integer;
birthday: string[24];
end;
{ 复制文件,也就是最后一种操作类型块数据 }
procedure FileCopy(const FileFrom, FileTo: string);
var
FromF, ToF: file;
NumRead, NumWritten: Integer;
Buffer: array [1 .. 2048] of Byte;
begin
{ 关联文件 }
AssignFile(FromF, FileFrom);
{ 读 }
Reset(FromF, 1);
{ 关联文件 }
AssignFile(ToF, FileTo);
{ 写 }
Rewrite(ToF, 1);
{ 完成边读边写,即复制的动作 }
repeat
BlockRead(FromF, Buffer, SizeOf(Buffer), NumRead);
BlockWrite(ToF, Buffer, NumRead, NumWritten);
until (NumRead = 0) or (NumWritten <> NumRead);
{ 释放两个文件资源 }
CloseFile(FromF);
CloseFile(ToF);
end;
// **********************************************************结构体读写
procedure ReadRecord();
var
{ 文件对象或者称为文件句柄,标注文件的类型 }
DataFile: file of TPersonRec;
PersonRec: TPersonRec;
begin
AssignFile(DataFile, 'E:\demo1.txt');
{ 读取方式 }
Reset(DataFile);
{ 执行读取 }
while not Eof(DataFile) do begin
Read(DataFile, PersonRec);
Writeln(PersonRec.name);
Writeln(IntToStr(PersonRec.age));
Writeln(PersonRec.birthday);
end;
{ 关闭,释放资源 }
CloseFile(DataFile);
end;
procedure WriteRecord();
var
{ 文件对象或者称为文件句柄,标注文件的类型 }
DataFile: file of TPersonRec;
PersonRec: TPersonRec;
begin
{ 创建结构体数据 }
PersonRec.name := '李四';
PersonRec.age := 81;
PersonRec.birthday := '1927-11-11';
AssignFile(DataFile, 'E:\demo1.txt');
{ 覆盖写入 }
Rewrite(DataFile);
{ 执行写入 }
Write(DataFile, PersonRec);
{ 关闭,释放资源 }
CloseFile(DataFile);
end;
// **********************文本读写*********************************************
procedure ReadText();
var
{ 文件对象或者称为文件句柄,标注文件的类型 }
TextFile: Text;
Content: string;
begin
AssignFile(TextFile, 'E:\demo1.txt');
{ 只读打开 }
Reset(TextFile);
{ Eof确定与句柄关联的文件是否已达到文件结束。 }
while not Eof(TextFile) do begin
{ 读取 }
Readln(TextFile, Content);
{ 显示 }
Writeln(Content);
end;
{ 关闭,释放资源 }
CloseFile(TextFile);
end;
procedure WriteText();
var
{ 文件对象或者称为文件句柄,标注文件的类型 }
TextFile: Text;
Content: string;
begin
Content := '期待哔哩哔哩粉丝过万';
AssignFile(TextFile, 'E:\demo1.txt');
{ 追加,即另外一种写的方式 }
// Append(TextFile);
{ 写入打开 }
Rewrite(TextFile);
Writeln(TextFile, Content);
{ 关闭,释放资源 }
CloseFile(TextFile);
end;
begin
//ReadRecord();
Readln;
end.
C语言风格的API
此套API不像上面的操作,而是全部采用字节的方式进行读取,因为 System.SysUtils 单元的函数很多我做了一下梳理
FileOpen
{函数原型}
function FileOpen(const FileName: string; Mode: LongWord): THandle;
描述信息
- 使用指定的访问模式打开指定的文件
参数介绍
FileName:基本上不需要介绍就是文件名
Mode:它的取值是以下几种
Value | Meaning |
fmOpenRead | Open the file for reading only. |
fmOpenWrite | Open the file for writing only. Writing to the file completely replaces the current contents. |
fmOpenReadWrite | Open the file to modify the current contents rather than replace them. |
fmShareCompat | Sharing is compatible with the way FCBs are opened. |
fmShareExclusive | Other applications cannot open the file for any reason. |
fmShareDenyWrite | Other applications can open the file for reading, but not for writing. |
fmShareDenyRead | Other applications can open the file for writing, but not for reading. |
fmShareDenyNone | No attempt is made to prevent other applications from reading from or writing to the file. |
我没有做翻译,和前面的套路类似,只是感觉Delphi重新做了封装
FileRead
官方描述:Reads a specified number of bytes from a file.
译文:从文件中读取指定的字节数。
{函数原型}
function FileRead(Handle: THandle; var Buffer; Count: LongWord): Integer;
function FileRead(Handle: THandle; var Buffer: TBytes; Offset, Count: LongWord): Integer;
为什么有两个,很明显是重载的函数,这个没关系,根据我们自己的情况进行调用即可
参数介绍
Handle:很明显就是前面的文件句柄
Buffer:一个缓冲区指针
Count:读取的长度
有了这个函数感觉就可以开干了
FileSeek
官方描述:Repositions read/write point.
译文:重新定位读/写点。
{函数原型}
function FileSeek(Handle: THandle; Offset, Origin: Integer): Integer;
function FileSeek(Handle: THandle; const Offset: Int64; Origin: Integer): Int64;
参数描述
Handle:文件句柄(或者称为文件指针)
Offset:翻译过来是偏移量
Origin:翻译过来是原点的意思,它有 3 个取值
Origin | Action |
0 | The file pointer is positioned Offset bytes from the beginning of the file. |
1 | The file pointer is positioned Offset bytes from its current position. |
2 | The file pointer is positioned Offset bytes from the end of the file. |
FileWrite
官方描述:Writes the contents of a buffer to the current position in a file.
译文:将缓冲区的内容写入文件中的当前位置。
{函数原型}
function FileWrite(Handle: THandle; const Buffer; Count: LongWord): Integer;
function FileWrite(Handle: THandle; const Buffer:TBytes; Offset, Count: LongWord): Integer;
参数描述
Handle:文件句柄
Buffer:缓冲区
Count:写入的长度,理论上应该就是缓冲区的长度
Offset:偏移量
FileClose
官方描述:Closes a specified file.
{函数原型}
procedure FileClose(Handle: THandle);
Handle:文件句柄
案例代码
核心函数就这么几个,案例也不需要我来写,官方提供了案例,我拿过来而已
读数据:http://docwiki.embarcadero.com/CodeExamples/Sydney/en/FileRead_(Delphi)
写数据:http://docwiki.embarcadero.com/CodeExamples/Sydney/en/FileToGrid_(Delphi)
新版API
官方文档:http://docwiki.embarcadero.com/Libraries/Sydney/en/System.IOUtils
这个单元包括三个主要的类:TPath, TDirectory, TFile,基本上都是和文件及文件夹相关
官方文档:http://docwiki.embarcadero.com/Libraries/Sydney/en/System.Classes
案例代码
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Classes, System.IOUtils, System.SysUtils;
type
{ 测试数据 }
TPerson = record
Name: string;
Age: Integer;
end;
{ 写文本数据 }
procedure WriteLine();
var
StreamWrite: TStreamWriter;
begin
// 创建TStreamWriter
StreamWrite := TStreamWriter.Create('E:\Demo\Person.txt');
// 写入数据
StreamWrite.WriteLine('期待哔哩哔哩粉丝过万');
// 释放资源
FreeAndNil(StreamWrite);
end;
{ 读取文本数据 }
procedure ReadLine();
var
Reader: TStreamReader;
begin
// 创建TStreamWriter
Reader := TStreamReader.Create('E:\Demo\Person.txt', TEncoding.ANSI);
// 读取数据
while not Reader.EndOfStream do begin
// 读取内容
Writeln(Reader.ReadLine);
end;
// 释放资源
FreeAndNil(Reader);
end;
{ 读结构体数据 }
procedure ReadRec();
var
FileStream: TFileStream;
var
Person: TPerson;
begin
try
FileStream := TFileStream.Create('E:\Demo\Person.txt', fmOpenRead);
// 设置文件指针的位置
FileStream.Position := 0;
// 遍历流中的数据(字节)
while FileStream.Position < FileStream.Size do begin
FileStream.Read(Person, sizeof(Person));
Writeln(Person.Name + ',' + Person.Age.ToString);
end;
finally
FreeAndNil(FileStream);
end;
end;
{ 写结构体数据 }
procedure WriteRec();
var
FileStream: TFileStream;
var
Person: TPerson;
begin
try
FileStream := TFileStream.Create('E:\Demo\Person.txt', fmCreate);
// 构造结构体数据
Person.Name := '萧蔷';
Person.Age := 20;
// 写出数据
FileStream.Write(Person, sizeof(Person));
finally
FreeAndNil(FileStream);
end;
end;
// *****************************************读写字节数据
{ 文件复制 }
procedure FIleCopy();
var
WriteFileStream, ReadFileStream: TFileStream;
begin
try
// 创建对象
ReadFileStream := TFileStream.Create('D:\常用软件下载.txt', fmOpenRead);
WriteFileStream := TFileStream.Create('E:\Demo\a.txt', fmCreate);
// 设置读取的位置
ReadFileStream.Position := 0;
WriteFileStream.CopyFrom(ReadFileStream, ReadFileStream.Size);
finally
FreeAndNil(ReadFileStream);
FreeAndNil(WriteFileStream);
end;
end;
{ 写数据 }
procedure WriteStringByByte();
var
FileStream: TFileStream;
var
Str: string;
var
StrByte: TBytes;
begin
// 字符串的长度、字符编码 Unicode、utf-8、gbk
Str := '期待B站粉丝破万';
try
FileStream := TFileStream.Create('D:\常用软件下载.txt', fmCreate);
// 将string转换为指定编码的字节数组
StrByte := TEncoding.UTF8.GetBytes(Str);
FileStream.WriteBuffer(StrByte, Length(StrByte));
finally
FreeAndNil(FileStream);
end;
end;
{ 读数据 }
procedure ReadUtf8String();
var
FileStream: TFileStream;
var
Str: UTF8String;
begin
FileStream := TFileStream.Create('D:\常用软件下载.txt', fmOpenRead);
FileStream.Position := 0;
// 缓冲区大小
SetLength(Str, FileStream.Size);
// 读取数据:解除指针引用,获取变量中的值
FileStream.Read(PChar(Str)^, FileStream.Size);
Writeln(Str);
FreeAndNil(FileStream);
end;
begin
ReadUtf8String();
Readln;
end.
PS:Delphi文件操作这块乱七八糟的的,网络上的代码也参差不齐,很容易陷入死胡同,以上内容仅仅是常规操作并没有和VCL组件进行整合
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)