VC 复制移动删除重命名文件文件夹



VC 复制移动删除重命名文件文件夹。

说明:

1.以下封装了4个函数_CopyFile,_DeleteFile,_MoveFile,_ReNameFile

2.每个函数都先拷贝了原来的路径,保证了路径是以2个\0\0结尾。(如果不以2个\0\0结尾,往往会出错)

3.对于文件或文件夹都适用

 

 

/*

能产生对话框的标志:

FOF_SILENT //progress dialog

FOF_RENAMEONCOLLISION //replace dialog

FOF_NOCONFIRMATION //confirmation dialog

FOF_NOCONFIRMMKDIR //asks for your permission to create a new folder

FOF_NOERRORUI //error message

 

FOF_ALLOWUNDO //允许放回回收站,一般这个最好做默认

FOF_NOCONFIRMATION //不出现确认对话框(当需要覆盖时)

FOF_SILENT //不显示进度对话框

FOF_NOERRORUI //No user interface will be displayed if an error occurs.

FOF_NOCONFIRMMKDIR //如果目的目录不存在,就默认创建,不需确认

FOF_RENAMEONCOLLISION //如果文件(夹)已存在,自动为其添加序列号修改文件名。此时不会出现确认对话框

FOF_MULTIDESTFILES //把文件夹里的所有内容复制到FileOp.pTo指定的文件夹里,而不是直接复制一个文件夹

FOF_SIMPLEPROGRESS //Displays a progress dialog box but does not show the file names

FOF_CONFIRMMOUSE //Not currently implemented.

FOF_FILESONLY: //执行通配符,只执行文件;

FOF_WANTMAPPINGHANDLE: //要求SHFileOperation()函数返回正处于操作状态的实际文件列表,文件列表

名柄保存在hNameMappings成员中。SHFILEOPSTRUCT结构还包含一个SHNAMEMAPPING结构的数组,此数组

保存由SHELL计算的每个处于操作状态的文件的新旧路径。

 

 

说明:

1.以下封装了4个函数_CopyFile,_DeleteFile,_MoveFile,_ReNameFile

2.每个函数都先拷贝了原来的路径,保证了路径是以2个\0\0结尾。(如果不以2个\0\0结尾,往往会出错)

3.对于文件或文件夹都适用

*/

 

 

/****************************************************************************

复制文件或者文件夹,需要把路径添加2个\0\0

****************************************************************************/

static

bool _CopyFile(const TCHAR *_pFrom,const TCHAR *_pTo,WORD flags=FOF_NOCONFIRMATION)

{

TCHAR pTo[MAX_PATH]={0}; _tcscpy(pTo,_pTo);

TCHAR pFrom[MAX_PATH]={0}; _tcscpy(pFrom,_pFrom);

 

SHFILEOPSTRUCT FileOp={0};

FileOp.fFlags= flags;

FileOp.pFrom = pFrom;

FileOp.pTo = pTo;

FileOp.wFunc = FO_COPY;

return SHFileOperation(&FileOp) == 0;

}

 

/****************************************************************************

删除文件或者文件夹,需要把路径添加2个\0\0

****************************************************************************/

static

bool _DeleteFile(const TCHAR* _pFrom,WORD flags=FOF_ALLOWUNDO|FOF_NOCONFIRMATION)

{

TCHAR pFrom[MAX_PATH]={0}; _tcscpy(pFrom,_pFrom);

 

SHFILEOPSTRUCT FileOp={0};

FileOp.pFrom = pFrom;

FileOp.pTo = NULL; //一定要是NULL

FileOp.fFlags= flags;

FileOp.wFunc = FO_DELETE; //删除操作

return SHFileOperation(&FileOp) == 0;

}

 

/****************************************************************************

移动文件或者文件夹,需要把路径添加2个\0\0

****************************************************************************/

static

bool _MoveFile(const TCHAR *_pFrom,const TCHAR *_pTo,WORD flags=FOF_NOCONFIRMATION)

{

TCHAR pTo[MAX_PATH]={0}; _tcscpy(pTo,_pTo);

TCHAR pFrom[MAX_PATH]={0}; _tcscpy(pFrom,_pFrom);

 

SHFILEOPSTRUCT FileOp={0};

FileOp.fFlags= flags;

FileOp.pFrom = pFrom;

FileOp.pTo = pTo;

FileOp.wFunc = FO_MOVE;

return SHFileOperation(&FileOp) == 0;

}

 

/****************************************************************************

重命名文件或者文件夹

可以的话用 rename(buf,TempFilePath) (文件和文件夹都可以) because不需要把路径添加2个\0\0

****************************************************************************/

static

bool _ReNameFile(const TCHAR *_pFrom,const TCHAR *_pTo,WORD flags=FOF_NOCONFIRMATION)

{

TCHAR pTo[MAX_PATH]={0}; _tcscpy(pTo,_pTo);

TCHAR pFrom[MAX_PATH]={0}; _tcscpy(pFrom,_pFrom);

 

SHFILEOPSTRUCT FileOp={0};

FileOp.fFlags = flags;

FileOp.pFrom = pFrom;

FileOp.pTo = pTo;

FileOp.wFunc = FO_RENAME;

return SHFileOperation(&FileOp) == 0;

}

 

━━━━━━━━━━━━━━━━━━━━━━━━

以下来自网络:

参数详解:

Typedef struct _ShFILEOPSTRUCT

{

HWND hWnd; //消息发送的窗口句柄;

UINT wFunc; //操作类型

LPCSTR pFrom; //源文件及路径

LPCSTR pTo; //目标文件及路径

FILEOP_FLAGS fFlags; //操作与确认标志

BOOL fAnyOperationsAborted; //操作选择位

LPVOID hNameMappings; //文件映射

LPCSTR lpszProgressTitle; //文件操作进度窗口标题

}SHFILEOPSTRUCT, FAR * LPSHFILEOPSTRUCT;

在这个结构中,hWnd是指向发送消息的窗口句柄,pFrom与pTo是进行文件操作的源文件名和目标文件名,它包含文件的路径,对应单个文件的路径字符串,或对于多个文件,必须以NULL作为字符串的结尾或文件路径名之间的间隔,否则在程序运行的时候会发生错误。另外,pFrom和pTo都支持通配符 *和?,这大大方便了开发人员的使用。例如,源文件或目录有两个,则应是:char pFrom[]=”d:\\Test1\0d:\\Text.txt\0″,它表示对要D:盘Test目录下的所有文件和D:盘上的Text.txt文件进行操作。字符串中的”\\”是C语言中的’\'的转义符,’\0′则是NULL。wFunc 是结构中的一个非常重要的成员,它代表着函数将要进行的操作类型,它的取值为如下:

FO_COPY: 拷贝文件pFrom到pTo 的指定位置。

FO_RENAME: 将pFrom的文件名更名为pTo的文件名。

FO_MOVE: 将pFrom的文件移动到pTo的地方。

FO_DELETE: 删除pFrom指定的文件。

使用该函数进行文件拷贝、移动或删除时,如果需要的时间很长,则程序会自动在进行的过程中出现一个无模式的对话框(Windows操作系统提供的文件操作对话框),用来显示执行的进度和执行的时间,以及正在拷贝、移动或删除的文件名,此时结构中的成员lpszProgressTitle显示此对话框的标题。fFlags是在进行文件操作时的过程和状态控制标识。它主要有如下一些标识,也可以是其组合:

FOF_ALLOWUNDO //允许放回回收站,一般这个最好做默认

FOF_NOCONFIRMATION //不出现确认对话框(当需要覆盖时)

FOF_SILENT //不显示进度对话框

FOF_NOERRORUI //No user interface will be displayed if an error occurs.

FOF_NOCONFIRMMKDIR //如果目的目录不存在,就默认创建,不需确认

FOF_RENAMEONCOLLISION //如果文件(夹)已存在,自动为其添加序列号修改文件名。此时不会出现确认对话框

FOF_MULTIDESTFILES //把文件夹里的所有内容复制到FileOp.pTo指定的文件夹里,而不是直接复制一个文件夹

FOF_SIMPLEPROGRESS //Displays a progress dialog box but does not show the file names

FOF_CONFIRMMOUSE //Not currently implemented.

FOF_FILESONLY: //执行通配符,只执行文件;

FOF_WANTMAPPINGHANDLE: //要求SHFileOperation()函数返回正处于操作状态的实际文件列表,文件列表

名柄保存在hNameMappings成员中。SHFILEOPSTRUCT结构还包含一个SHNAMEMAPPING结构的数组,此数组

保存由SHELL计算的每个处于操作状态的文件的新旧路径。

转自http://blog.csdn.net/jhb92/archive/2007/04/13/1563452.aspx

Shell的文件操作函数


SHFileOperation

功能:

1.复制一个或多个文件

2.删除一个或多个

3.重命名文件

4.移动一个或多个文件

有一样的Win32API功能函数是:

CopyFile(),DeleteFile(),MoveFile()

MoveFile可以对文件重命名!

Win32 API 的层次比SHFileOperation低

SHFileOperation

的重要参数

1.wFunc //对pFrom pTo要执行的操作

2.fFlags //影响对wFunx的操作

3.hNameMappings //有系统填充,和你也可以填充

4.lpszProgressTitle

pFrom pTo 在结尾是两个’\0\0′

通常用一个’\0′,这样会失败的!!

当FOF_MULTIDESTFILES

szPFrom[lstrlen(szPFrom)+1]=0

szPFrom:必须先确定他所指定的文件存在!

可以是单个文件名,*.*,或包含统配符的文件名

注意必须是文件名,不是文件所在的文件夹名

szSource:可以是一个目录,如果不是目录,但又有

多个文件,那么必须和szPFrom的每一个文件对应,还要指定

FOF_MULTIDETFILES标志

Source and Target

多个文件—> 一个文件夹

许多单独的文件—->一个文件夹

单独文件—>单独文件

许多单独的文件—->许多单独的文件

单独文件:知道名字的文件

多个文件:带有统配符的文件

注意到source中没有对文件夹的操作!!

!!!!

SHFileOperation能操作网络上的文件

如果你想将本地文件复制到192.168.1.99

那么只要在192.168.1.99上共享123目录

然后将pTo设置为\\192.168.1.99\123

就可以了

但不要设置为\\192.168.1.99

对hNameMappings操作是Undocumented!!

如果没有指定hNameMappings

那么hNameMappings一直是NULL

只有当某种操作(copy,move,rename)引起了文件名冲突了,hNameMappings才不是NULL!!!

当第一次copy某些文件到空目录中时hNameMappings一定是NULL

所以hNameMappings只是内存中的一块地区用来让Explorer.exe保存被重命名的文件,以避免文件名冲突!

上面知道了如何才能使hNameMappings有效

现在如何使用hNameMappings,及其所指的结构大小?并取得这个内存块的内容呢?

hNameMappings 是简单LPVOID无法使用loop

要使用hNameMappings,必须定义一个结构体

struct HANDLETOMAPPINGS {

UINT uNumberOfMappings; // number of mappings in array

LPSHNAMEMAPPING lpSHNameMapping; // pointer to array of mappings

};

但是可以写一个Enumerate function to enumerate lpSHNameMapping指向的内存块,并且是让Window自己调用我的,不是我主动调用,象Loop

 

 

另外2个删除文件夹的函数:

//删除文件夹目录(非空)

bool DeleteDirectory(char* sDirName)

{

CFileFind tempFind;

char sTempFileFind[200] ;

 

sprintf(sTempFileFind,”%s*.*”,sDirName);

BOOL IsFinded = tempFind.FindFile(sTempFileFind);

while (IsFinded)

{

IsFinded = tempFind.FindNextFile();

 

if (!tempFind.IsDots())

{

char sFoundFileName[200];

strcpy(sFoundFileName,tempFind.GetFileName().GetBuffer(200));

 

if (tempFind.IsDirectory())

{

char sTempDir[200];

sprintf(sTempDir,”%s\%s”,sDirName,sFoundFileName);

DeleteDirectory(sTempDir);

}

else

{

char sTempFileName[200];

sprintf(sTempFileName,”%s\%s”,sDirName,sFoundFileName);

_DeleteFile(sTempFileName);

}

}

}

tempFind.Close();

if(!RemoveDirectory(sDirName))

{

return FALSE;

}

return TRUE;

}

 

 

//下面是应用,CString m_strDir 是一个文件夹路径,如:d:downloadpic

 

BOOL DelAll()

{

if(PathFileExists(m_strDir))

DeleteDirectory((LPSTR)(LPCTSTR)m_strDir);

return 1;

}

 

 

 

// 删除文件夹及其所有内容

void RemoveFolder(const CString &strPathName)

{

CString path = strPathName;

if (path.Right(1) != _T(“\\”))

path += _T(“\\”);

path += _T(“*.*”);

 

CFileFind ff;

BOOL res = ff.FindFile(path);

while (res)

{

res = ff.FindNextFile();

// 是文件时直接删除

if (!ff.IsDots() && !ff.IsDirectory())

DeleteFile(ff.GetFilePath());

else if (ff.IsDots())

continue;

else if (ff.IsDirectory())

{

path = ff.GetFilePath();

// 是目录时继续递归,删除该目录下的文件

RemoveFolder(path);

::RemoveDirectory(path);

}

}

}