Delphi磁盘操作编程技巧三则
软件世界
一、检测软盘或光盘是否有变化
一般情况下,不同的软盘或光盘具有不同的卷标号,因此, 我们可以通过检测卷标号的变化,来确定软盘或光盘是否更换过。恰好,Windows API 中提供了GetVolumeInformation函数来获取软盘、硬盘和光盘的卷标号,为我们实现此项功能提供了方便。
函数原型:
BOOL GetVolumeInformation(
LPCTSTR lpRootPathName,
LPTSTR lpVolumeNameBuffer,
DWORD nVolumeNameSize,
LPDWORD lpVolumeSerialNumber,
LPDWORD lpMaximumComponentLength,
LPDWORD lpFileSystemFlags,
LPTSTR lpFileSystemNameBuffer,
DWORD nFileSystemNameSize
);
有关的参数说明:
1.lpRootPathName:指定测试驱动器的根目录的名称,若为null时,则指定为当前目录所在驱动器的根目录名称。
2.LpVolumeNameBuffer:指定存放驱动器卷标名称缓冲区的首址。不需要时,设为nil。
3.nVolumeNameSize:指定存放驱动器卷标名称缓冲区的大小。不需要时,设为0。
4.LpVolumeSerialNumber:指定存放驱动器卷标号缓冲区的首址。不需要时,设为nil。
5.LpMaximumComponentLength:指明驱动器可支持的文件名的最大长度。必须有参数。
6.LpFileSystemFlags:指明文件系统特性标志,如是压缩方式还是非压缩方式等等。必须有参数。
7.LpFileSystemNameBuffer:指明文件系统类型名称的存放缓冲区首址,FAT或NTFS等等。不需要时,设为nil。
8.NFileSystemNameSize: 指明文件系统类型名称的存放缓冲区大小。不需要时,设为0。
应用举例:
检测软盘是否发生变化。
(1)建立一新工程。
(2)在窗体FORM1中添加两个LABEL1组件,一个COMBOBOX组件和一个EDIT1组件。将COMBOBOX组件的ITEMS属性设置为“A:”。如((图1)):

(3)在Tform1定义中增加一个新的函数声明信息,定义一个变量。如下:
type
Tform1=class(Tform)
...
private
//定义新函数,该函数用来获取一个驱动器的卷标号。
function GetDiskVolID(DriveName:String):Dword; public
...
var
// 定义一个变量,用来存放前一次测试A盘获取的卷标号
saveolda:string;
(4)函数GetDiskVolId定义体如下:
function GetDiskVolId(DriveName:String):Dword;
var
p1,p2:dword;
p3:dword;//指向卷标号存放的地址
begin
new(p3);
//调用getvolumeinformation函数获取卷标号
getvolumeinformation(pchar(drivename+'\'),nil,0,p3,p1,p2,nil,0);
result:=p3^;
dispose(p3);
end;
(5)在combobox组件的onchange 事件中调用GetDiskVolID函数。
Procedure tform1.Combobox1change(sender:tobject);
Var
savenewa:string//定义变量,存放最新测试A盘获取的卷标号
Begin
savenewa:=inttostr(GetDiskVolID(combobox1.Items[combobox1.Itemindex]));
if savenewa <>'' then //判断是否取得卷标号
if saveolda <> savenewa then //比较前后卷标号是否发生改变
begin
//提示信息
Application.MessageBox('A盘发生更换!','磁盘打开错误!', MB_DEFBUTTON1);
edit1.text:=savenewa;
saveolda:=savenewa;
end;
End;
二、检测驱动器容量
可以利用Windows API 函数GetDiskFreeSpace完成。
函数原型:
BOOL GetDiskFreeSpace(
LPCTSTR lpRootPathName,
LPDWORD lpSectorsPerCluster,
LPDWORD lpBytesPerSector,
LPDWORD lpNumberOfFreeClusters,
LPDWORD lpTotalNumberOfClusters
);
参数说明:
1.lpRootPathName:指定测试驱动器的根目录的名称。为null时,则为当前目录所在驱动器的根目录名称。
2.LpSectorsPerCluster:取得驱动器每簇的扇区数。
3.LpBytesPerSector:取得驱动器每扇区的字节数。
4.LpNumberOfFreeClusters:磁盘剩余空间的簇数。
5.LpTotalNumberOfClusters:磁盘总空间的簇数。
应用举例:
显示磁盘空间的总容量,剩余容量。
1) 在上例基础上,添加两个edit组件和两个label组件,如((图2)):

2) 在combobox组件的onchange 事件相应部分添加如下内容:
val
disktotal,diskfree,cl1,cl2,sec1,byt1:longword;
begin
Getdiskfreespace(pchar(combobox1.Items[combobox1.Itemindex]),sec1,byt1,cl1,cl2);//获取磁盘信息
Diskfree:=cl1*sec1*byt1;//剩余容量=剩余簇数*每簇扇区数*每扇区字节数
disktotal:=cl2*sec1*byt1;//总容量=磁盘总簇数*每簇扇区数*每扇区字节数
edit2.text:=formatfloat('###,##0',total);
edit3.text:=formatfloat('###,##0',freesp);
end;
三、检测驱动器是否就绪
利用delphi自带的disksize函数,检测是否返回指定磁盘的字节数来实现。
函数原型:
function disksize(driver:byte):int64
参数说明:
driver:指明磁盘所对应的编号值。如在delphi中规定A盘编号为1;C盘编号为3。
应用举例:
接上例,在combobox组件的onchange 事件开始部分添加如下内容:
if disksize (1)=-1 then
begin
Application.MessageBox('A盘没准备好!','磁盘操作错误', MB_DEFBUTTON1);
Exit;
End;
实际上通过第2例的函数,我们也可以完成此操作,实际应用中主要看你对哪个函数熟悉了。上述事例在Delphi5.0通过。