c++Builder 下的文件及目录操作
转自 http://blog.csdn.net/ktcserver/article/details/936329
一、判断目录是否存在:
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");
c++Builder 下的文件及目录操作的更多相关文章
- Linux下的文件与目录操作 BY 四喜三顺
文件操作权限: chmod 三个八进制数字 文件名 其中:三个八进制数字,第一个代表本用户的权限,第二个代表同组的权限,第三个代表其他用户的权限4代表可读2代表可写1代表可执行例如:chmod 7 ...
- linux系统下修改文件夹目录权限
linux系统下修改文件夹目录权限 文件夹权限问题 Linux.Fedora.Ubuntu修改文件.文件夹权限的方法差不多.很多人开始接触Linux时都很头痛Linux的文件权限问题.这里告诉大家如何 ...
- Python::OS 模块 -- 文件和目录操作
os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...
- Python之文件与目录操作及压缩模块(os、shutil、zipfile、tarfile)
Python中可以用于对文件和目录进行操作的内置模块包括: 模块/函数名称 功能描述 open()函数 文件读取或写入 os.path模块 文件路径操作 os模块 文件和目录简单操作 zipfile模 ...
- 零基础学Python--------第10章 文件及目录操作
第10章 文件及目录操作 10.1 基本文件操作 在Python中,内置了文件(File)对象.在使用文件对象时,首先需要通过内置的open() 方法创建一个文件对象,然后通过对象提供的方法进行一些基 ...
- Shell命令-文件及目录操作之cp、find
文件及目录操作 - cp.find 1.cp:复制文件或目录 cp命令的功能说明 cp命令用于复制文件或目录. cp命令的语法格式 cp [OPTION]... SOURCE... DIRECTORY ...
- Shell命令-文件及目录操作之mkdir、mv
文件及目录操作 - mkdir.mv 1.mkdir:创建目录 mkdir命令的功能说明 mkdir命令用于创建目录,默认情况下,要创建的目录已存在,会提示文件存在,不会继续创建目录. mkdir命令 ...
- Shell命令-文件及目录操作之touch、tree
文件及目录操作 - touch.tree 1.touch:创建文件或更改文件时间戳 touch命令的功能说明 touch命令用于创建新的空文件或改变已有文件的时间戳属性. touch命令的语法格式 t ...
- Shell命令-文件及目录操作之chattr、lsattr
文件及目录操作 - chattr.lsattr 1. chattr:改变文件属性 chattr命令的功能说明 chattr命令用于改变文件属性.这项指令可改变存放在ext2文件系统上的文件或目录属性, ...
随机推荐
- Hadoop MapReduce概念学习系列之mr的Shuffle(二十二)
Shuffle是非常非常非常重要.搞mr,必须熟烂于心. 因为,分区,分组,排序,,,都是在Shuffle里完成.
- git http方式时保存密码
一直使用ssh方式,但是git@osc的ssh只能pull,不能push - -||| htts方式保存密码老是忘记,每次提交代码都要输入密码烦死了.找到文章备忘: 转自:http://git ...
- SQL2008-查询库中是否存在某表
select * from sysobjects where name= 'N201111B' and xtype= 'U'
- hdoj 1106 排序
排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submissi ...
- vss2005使用
http://www.cnblogs.com/nianyuwen/archive/2012/06/13/2547588.html 签出状态的文件别人无法使用:
- selenium 自动化测试面试题及答案
写在开始: 这些问题和答案,都是自己在网上找的,整理的,有任何问题,概不负责.主要感谢博主Ray,http://www.cnblogs.com/tsbc/p/4922368.html 1.seleni ...
- gmt学习资源
1 http://seisman.info/ http://examples.gmt-china.org/ http://docs.gmt-china.org http://modules.gmt-c ...
- MFC 学习 之 状态栏的添加
1.首先声明一个 CStatusBar m_bar;//声明对象2.然后打开视图资源 String Table中添加两个字段值 3.创建了两个字段值以后,在OnintDialog() 所在的 .cp ...
- Python、C和Java对比
先上一个Python小测试: #!/usr/bin/env python #coding=utf-8 ''' 等腰三角形 ''' for i in range(1,6): print ' '*(6-i ...
- C#WinForm应用程序实现自动填充网页上的用户名和密码并点击登录按钮【转载】
使用WebBrowser控件,在documentComplete事件处理器里写 HtmlElement name = webBrowser1.Document.GetElementById(" ...