Delphi 2010 新增功能之: IOUtils 单元
(1): 初识 TDirectory.GetFiles
用 IOUtils 单元下的 TDirectory.GetFiles 获取文件列表太方便了;
下面的例子只是 TDirectory.GetFiles 的典型应用…
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;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses IOUtils, Types;
{这是随意拿来的测试路径}
const path = 'C:\Program Files\Embarcadero\RAD Studio\7.0';
//获取指定目录下的所有文件
procedure TForm1.Button1Click(Sender: TObject);
var
dir: TDirectory; {这是个结构, 后面就不再声明了, 将直接使用}
files: TStringDynArray; {TStringDynArray = array of string;}
str: string;
begin
files := dir.GetFiles(path);
Memo1.Clear;
for str in files do Memo1.Lines.Add(str);
end;
//获取指定目录下的所有指定类型的文件
procedure TForm1.Button2Click(Sender: TObject);
var
files: TStringDynArray;
str: string;
begin
files := TDirectory.GetFiles(path, '*.txt');
Memo1.Clear;
for str in files do Memo1.Lines.Add(str);
end;
//获取指定目录及其嵌套目录下的所有指定类型的文件
procedure TForm1.Button3Click(Sender: TObject);
var
files: TStringDynArray;
str: string;
begin
files := TDirectory.GetFiles(path, '*.txt', TSearchOption.soAllDirectories);
Memo1.Clear;
for str in files do Memo1.Lines.Add(str);
end;
end.
(2): TDirectory.TFilterPredicate
TDirectory.GetFiles 函数还有一个 TDirectory.TFilterPredicate 类型的参数, 这是个匿名函数类型, 可对搜索结果再处理.
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;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses IOUtils, Types;
const path = 'C:\Program Files\Embarcadero\RAD Studio\7.0';
//准备给 TDirectory.GetFiles 调用的函数, 须符合 TDirectory.TFilterPredicate 格式
function fp(const Path: string; const SearchRec: TSearchRec): Boolean;
begin
Form1.Memo1.Lines.Add(Path + '\' + SearchRec.Name);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
files: TStringDynArray;
begin
Memo1.Clear;
files := TDirectory.GetFiles(path, fp);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
files: TStringDynArray;
begin
Memo1.Clear;
files := TDirectory.GetFiles(path, '*.txt', fp);
end;
procedure TForm1.Button3Click(Sender: TObject);
var
files: TStringDynArray;
begin
Memo1.Clear;
files := TDirectory.GetFiles(path, '*.txt', TSearchOption.soAllDirectories, fp);
end;
//可以这样方便地使用匿名函数
procedure TForm1.Button4Click(Sender: TObject);
var
files: TStringDynArray;
begin
Memo1.Clear;
files := TDirectory.GetFiles(path,
function(const Path: string; const SearchRec: TSearchRec): Boolean
begin
Memo1.Lines.Add(Path + '\' + SearchRec.Name);
end
);
end;
end.
(3): TDirectory.GetFiles 支持通配符
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses IOUtils, Types;
const path = 'C:\Program Files\Embarcadero\RAD Studio\7.0';
//获取指定目录下有 Li 开头的文件
procedure TForm1.Button1Click(Sender: TObject);
var
files: TStringDynArray;
str: string;
begin
files := TDirectory.GetFiles(path, 'Li*.*');
Memo1.Clear;
for str in files do Memo1.Lines.Add(str);
end;
//获取指定目录及其子目录下文件名只有 3 个字母的 pas 文件
procedure TForm1.Button2Click(Sender: TObject);
var
files: TStringDynArray;
str: string;
begin
files := TDirectory.GetFiles(path, '???.pas', TSearchOption.soAllDirectories);
Memo1.Clear;
for str in files do Memo1.Lines.Add(str);
end;
end.
(4): TDirectory.GetDirectories
和 TDirectory.GetFiles 用法一样, TDirectory.GetDirectories 是用来获取子目录的.
另外还有 TDirectory.GetFileSystemEntries 可同时获取文件与子目录, 用法都一样.
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;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses IOUtils, Types;
const path = 'C:\Program Files\Embarcadero\RAD Studio\7.0';
//获取指定目录下的文件与子目录
procedure TForm1.Button1Click(Sender: TObject);
var
dfs: TStringDynArray;
str: string;
begin
dfs := TDirectory.GetFileSystemEntries(path);
Memo1.Clear;
for str in dfs do Memo1.Lines.Add(str);
end;
//获取指定目录下的、名称是 L 开头的文件与子目录
procedure TForm1.Button2Click(Sender: TObject);
var
dfs: TStringDynArray;
str: string;
begin
dfs := TDirectory.GetFileSystemEntries(path, 'L*');
Memo1.Clear;
for str in dfs do Memo1.Lines.Add(str);
end;
//获取指定目录及嵌套目录下的所有文件与子目录
procedure TForm1.Button3Click(Sender: TObject);
var
dfs: TStringDynArray;
str: string;
begin
dfs := TDirectory.GetFileSystemEntries(path + '\source', TSearchOption.soAllDirectories, nil);
Memo1.Clear;
for str in dfs do Memo1.Lines.Add(str);
end;
//使用 TDirectory.TFilterPredicate 函数参数
procedure TForm1.Button4Click(Sender: TObject);
var
dfs: TStringDynArray;
begin
Memo1.Clear;
dfs := TDirectory.GetFileSystemEntries(path,
function(const Path: string; const SearchRec: TSearchRec): Boolean
begin
//这里可以有更多过滤条件或其他处理
Memo1.Lines.Add(Path + '\' + SearchRec.Name);
end
);
end;
end.
(5): TDirectory 的其他功能
TDirectory.CreateDirectory(); {建立新目录}
TDirectory.Exists(); {判断文件夹是否存在}
TDirectory.IsEmpty(); {判断文件夹是否为空}
TDirectory.Copy(); {复制文件夹}
TDirectory.Move(); {移动文件夹}
TDirectory.Delete(); {删除文件夹, 第二个参数为 True 可删除非空文件夹}
TDirectory.GetDirectoryRoot(); {获取目录的根盘符, 如: C:\}
TDirectory.GetCurrentDirectory; {获取当前目录}
TDirectory.SetCurrentDirectory(); {设置当前目录}
TDirectory.GetLogicalDrives; {获取驱动器列表; 下有举例}
TDirectory.GetAttributes(); {获取文件夹属性, 譬如只读、存档等; 下有举例}
TDirectory.SetAttributes(); {设置文件夹属性; 下有举例}
{获取、设置文件建立时间、修改时间、读取时间}
TDirectory.GetCreationTime();
TDirectory.SetCreationTime();
TDirectory.GetLastWriteTime();
TDirectory.SetLastWriteTime();
TDirectory.GetLastAccessTime();
TDirectory.SetLastAccessTime();
{使用 Utc 时间格式读取或设置}
TDirectory.GetCreationTimeUtc();
TDirectory.SetCreationTimeUtc();
TDirectory.GetLastWriteTimeUtc();
TDirectory.SetLastWriteTimeUtc();
TDirectory.GetLastAccessTimeUtc();
TDirectory.SetLastAccessTimeUtc();
测试代码:
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;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses IOUtils, Types, TypInfo;
//TDirectory.GetLogicalDrives; {获取驱动器列表}
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
arr: TStringDynArray;
begin
arr := TDirectory.GetLogicalDrives;
Memo1.Clear;
for s in arr do Memo1.Lines.Add(s);
end;
//TDirectory.GetAttributes(); {获取文件夹属性, 譬如只读、存档等}
procedure TForm1.Button2Click(Sender: TObject);
var
fas: TFileAttributes;
fa: TFileAttribute;
begin
fas := TDirectory.GetAttributes('c:\Windows');
Memo1.Clear;
for fa := Low(TFileAttribute) to High(TFileAttribute) do
if fa in fas then Memo1.Lines.Add(GetEnumName(TypeInfo(TFileAttribute), Ord(fa)));
end;
//TDirectory.SetAttributes(); {设置文件夹属性, 这里是设置为隐藏}
procedure TForm1.Button3Click(Sender: TObject);
const
path = 'c:\temp\ABC';
begin
TDirectory.CreateDirectory(path);
TDirectory.SetAttributes(path, [TFileAttribute.faHidden]);
end;
end.
(6): TPath(结构体) 的方法与属性
以后路径相关的处理, 用 IOUtils.TPath 就很方便了.
//较常用的方法:
TPath.GetTempPath; {获取临时文件夹路径}
TPath.GetTempFileName; {获取一个临时文件名}
TPath.GetPathRoot(); {提取盘符, 如: c:\}
TPath.GetDirectoryName(); {提取路径}
TPath.GetFileName(); {提取文件名}
TPath.GetExtension(); {提取扩展名}
TPath.GetFileNameWithoutExtension(); {提取无扩展名的文件名}
TPath.ChangeExtension(); {更换扩展名}
TPath.DriveExists(); {检查路径中的驱动器是否存在}
TPath.GetFullPath(); {根据相对路径给出全路径}
TPath.HasExtension(); {判断是否有扩展名}
TPath.IsPathRooted(); {判断是否是绝对路径}
TPath.Combine(); {结合路径}
TPath.GetRandomFileName; {产生一个随机文件名}
TPath.GetGUIDFileName(); {用于产生一个唯一的文件名, 布尔参数决定名称中是否包含 -}
TPath.IsValidPathChar(); {判断给定的字符是否能用于路径名}
TPath.IsValidFileNameChar(); {判断给定的字符是否能用于文件名}
//不常用的方法
TPath.HasValidPathChars();
TPath.HasValidFileNameChars();
TPath.GetExtendedPrefix();
TPath.IsExtendedPrefixed();
TPath.IsUNCRooted();
TPath.IsDriveRooted();
TPath.IsUNCPath();
TPath.MatchesPattern();
TPath.GetInvalidFileNameChars;
TPath.GetInvalidPathChars;
TPath.GetAttributes();
TPath.SetAttributes();
//属性, 获取在不同平台下的各种路径分隔符, 都是只读的.
TPath.AltDirectorySeparatorChar; {Windows 下是 "\"}
TPath.AltDirectorySeparatorChar; {Windows 下是 "/"}
TPath.ExtensionSeparatorChar; {Windows 下是 "."}
TPath.PathSeparator; {Windows 下是 ";"}
TPath.VolumeSeparatorChar; {Windows 下是 ":"}
(7): TFile 结构的功能
IOUtils 单元主要就是三个结构: TDirectory、TPath、TFile, 很有用; 下面是 TFile 的功能简介.
TFile.Exists();
//判断指定的文件是否存在
TFile.Copy();
//复制文件
var
source,dest: string;
begin
TFile.Copy(source, dest); {不允许覆盖同名的文件}
TFile.Copy(source, dest, True); {将覆盖同名的文件}
end;
TFile.Move();
//移动文件
var
source,dest: string;
begin
TFile.Move(source, dest);
end;
TFile.Delete();
//删除文件
TFile.Replace();
//替换文件, dest 会备份在 bak, 复制 source 的内容到 dest 后, sourece 会被删除.
var
source,dest,bak: string;
begin
source := 'c:\temp\t1.txt';
dest := 'c:\temp\t2.txt';
bak := 'c:\temp\t3.txt';
TFile.Replace(source, dest, bak); {前两个文件必须存在}
TFile.Replace(source, dest, bak, True); {忽略错误}
end;
TFile.Create();
//建立文件并返回一个和文件关联的 TFileStream, 指定文件存在则覆盖
var
buf: array[0..1023] of Byte;
fs: TFileStream;
begin
{模拟一个缓冲区并填充}
FillChar(buf, SizeOf(buf), 65);
{使用返回的 TFileStream 写入流}
fs := TFile.Create('c:\temp\test1.txt');
fs.Write(buf, SizeOf(buf));
fs.Free;
{如果已知要写入流的大小, 可以使用第二个参数指定, 这样会快一点}
fs := TFile.Create('c:\temp\test2.txt', SizeOf(buf));
fs.Write(buf, SizeOf(buf));
fs.Free;
end;
TFile.OpenWrite();
//按只写权限打开文件并返回一个和文件关联的 TFileStream
const
buf: array[0..2] of Char = ('A', 'B', 'C');
var
path: string;
fs: TFileStream;
begin
path := 'c:\temp\test.dat'; {文件要存在}
fs := TFile.OpenWrite(path);
fs.Seek(0, TSeekOrigin.soEnd); {把流指针移到尾部}
fs.Write(buf, Length(buf)*SizeOf(Char));
fs.Free;
end;
TFile.OpenRead();
//按只读权限打开文件并返回一个和文件关联的 TFileStream
var
path: string;
fs: TFileStream;
begin
path := 'c:\temp\test.dat'; {文件要存在}
fs := TFile.OpenRead(path);
ShowMessage(IntToStr(fs.Size));
fs.Free;
end;
TFile.Open();
//打开文件并返回一个和文件关联的 TFileStream
var
path: string;
fs: TFileStream;
begin
path := 'c:\temp\test.dat'; {文件要存在}
//重载一: 指定打开模式; 默认操作权限是 faReadWrite, 默认线程访问权限是 fsNone
fs := TFile.Open(path, TFileMode);
//重载二: 指定打开模式、操作权限; 默认线程访问权限是 fsNone
fs := TFile.Open(path, TFileMode, TFileAccess);
//重载三: 指定打开模式、操作权限和其他线程的访问权限
fs := TFile.Open(path, TFileMode, TFileAccess, TFileShare);
{ TFileMode 打开模式:
TFileMode.fmCreateNew 创建新文件, 如果文件已存在则将引发异常;
TFileMode.fmCreate 创建新文件, 如果文件已存在则覆盖;
TFileMode.fmOpen 打开现有文件, 如果该文件不存在则将引发异常;
TFileMode.fmOpenOrCreate 打开文件, 如果文件不存在则建新文件;
TFileMode.fmTruncate 打开现有文件并清空;
TFileMode.fmAppend 打开现有文件并把流指针移到文件尾, 如果文件不存在创建新文件.
}
{ TFileMode 操作权限:
TFileMode.faRead 只读;
TFileMode.faWrite 只写;
TFileMode.faReadWrite 可读写.
}
{ TFileShare 对其他线程的访问限制:
TFileMode.fsNone 禁止其他线程共享;
TFileMode.fsRead 允许其他线程读;
TFileMode.fsWrite 允许其他线程写;
TFileMode.fsReadWrite 允许其他线程读写.
}
end;
TFile.CreateText();
//建立文本文件, 存在则覆盖; 会返回 TStreamWriter
var
path: string;
sw: TStreamWriter;
begin
path := 'c:\temp\test.txt';
sw := TFile.CreateText(path); {使用的是 UTF8 格式}
sw.Write(123);
sw.Write('ABC');
sw.Close;
end;
TFile.AppendText();
//为追加而打开文本文件, 不存在则创建; 会返回 TStreamWriter
var
path: string;
sw: TStreamWriter;
begin
path := 'c:\temp\test.txt';
sw := TFile.AppendText(path); {使用的是 UTF8 格式}
sw.Write(123);
sw.Write('ABC');
sw.Close;
end;
TFile.AppendAllText();
//打开文本文件, 追加文本后关闭; 文件不存在则创建.
var
path: string;
begin
path := 'c:\temp\test.txt';
TFile.AppendAllText(path, 'NewString');
TFile.AppendAllText(path, 'NewString', TEncoding.UTF8); {可指定编码格式}
end;
TFile.OpenText();
//打开文本文件, 返回 TStreamReader.
var
path: string;
sr: TStreamReader;
begin
path := 'c:\temp\test.txt';
sr := TFile.OpenText(path); {将使用 UTF8 格式}
ShowMessage(sr.ReadLine);
sr.Close;
end;
TFile.WriteAllText();
//打开文本文件, 写入指定文本后关闭; 不管文件存在与否都将覆盖!
var
path: string;
begin
path := 'c:\temp\test.txt';
TFile.WriteAllText(path, '123');
TFile.WriteAllText(path, '123', TEncoding.UTF8); {可指定编码格式}
end;
TFile.WriteAllLines();
//打开文本文件, 写入指定的字符串数组后关闭; 不管文件存在与否都将覆盖!
var
path: string;
arr: TStringDynArray; {这定义在 Types 单元}
begin
SetLength(arr, 2);
arr[0] := 'AAA';
arr[1] := 'BBB';
path := 'c:\temp\test.txt';
TFile.WriteAllLines(path, arr);
TFile.WriteAllLines(path, arr, TEncoding.UTF8); {可指定编码格式}
end;
TFile.WriteAllBytes();
//打开文本文件, 写入指定的 TBytes 数组后关闭; 不管文件存在与否都将覆盖!
var
path: string;
bs: TBytes;
begin
SetLength(bs, 2);
bs[0] := 65;
bs[1] := 66;
path := 'c:\temp\test.txt';
TFile.WriteAllBytes(path, bs);
end;
TFile.ReadAllText();
//打开文本文件, 全部读取字符串变量后关闭.
var
path: string;
str: string;
begin
path := 'c:\temp\test.txt';
str := TFile.ReadAllText(path);
str := TFile.ReadAllText(path, TEncoding.UTF8); {可指定编码格式}
end;
TFile.ReadAllLines();
//打开文本文件, 全部读入到字符串数组后关闭.
var
path: string;
arr: TStringDynArray; {这定义在 Types 单元}
begin
path := 'c:\temp\test.txt';
arr := TFile.ReadAllLines(path);
arr := TFile.ReadAllLines(path, TEncoding.UTF8); {可指定编码格式}
ShowMessage(arr[0]);
end;
TFile.ReadAllBytes();
//打开文本文件, 全部读入到 TBytes 数组后关闭;
var
path: string;
bs: TBytes;
begin
path := 'c:\temp\test.txt';
bs := TFile.ReadAllBytes(path);
ShowMessage(IntToStr(Length(bs)));
end;
暂时测试有问题的方法:
TFile.Encrypt(); {加密文件}
TFile.Decrypt(); {解密文件}
其他方法:
{读取和设置属性的方法前面有过例子}
TFile.GetAttributes();
TFile.SetAttributes();
{读取和设置文件的建立时间、最后写入时间、最后访问时间(分别有本地和UTC两种时间格式)}
TFile.GetCreationTime();
TFile.GetCreationTimeUtc();
TFile.GetLastAccessTime();
TFile.GetLastAccessTimeUtc();
TFile.GetLastWriteTime();
TFile.GetLastWriteTimeUtc();
TFile.SetCreationTime();
TFile.SetCreationTimeUtc();
TFile.SetLastAccessTime();
TFile.SetLastAccessTimeUtc();
TFile.SetLastWriteTime();
TFile.SetLastWriteTimeUtc();
转自万一的博客,原文链接