前几天需要在Wince上进行文件拷贝, 自己用FindFirstFile 和 FindNextFile 实现了文件、目录的拷贝功能。为了能够在一个函数中同时Copy目录或文件,那么就需要首先判断你给的参数是个目录还是文件,然后进行相应的拷贝或者递归处理。虽然实现的还是有些缺点,比如没有处理给定的目录参数后面带反斜线的情况。
先定义打印log的宏和数组长度
#define
RETAILMSG(exp, m) if (exp) {_tprintf m;}
#define MAX_LENGTH 200
#define MAX_LENGTH 200
1. Copy 文件或目录 ----> 目录
思路: 先判断给定的输入是文件还是目录。如果是文件,则根据目标目录构建目标文件,并调用WinAPI copy文件,然后 return; 如果是目录,遍历该目录下的子文件或子目录,对于子文件拷贝;对于子目录,重新构建目的子目录并递归调用
代码
//
This Function can be used to copy source files/dirctory to destination directory
// ---Copy source direcotry to destination directory
// ---Copy source files to destination directory
BOOL CopyToDirecotry(WCHAR * pwszSourceDirectory,WCHAR * pwszDestDirectory)
{
BOOL result = TRUE;
WCHAR pwszSourceFullPath[MAX_LENGTH] = { 0 }; // each searched source full path
WCHAR pwszDestFullPath[MAX_LENGTH] = { 0 }; // each dest full path according to the source path
WCHAR pwszTempSource[MAX_LENGTH] = { 0 };
WCHAR pwszTempDest[MAX_LENGTH] = { 0 };
WIN32_FIND_DATA wfd;
HANDLE hFind = NULL;
// pwszTempSource represents the folders or files under the current source path
wcscpy(pwszTempSource,pwszSourceDirectory);
// pwszTempDest: concrete dest file or directory full path
wcscpy(pwszTempDest,pwszDestDirectory);
// Verify whether the destination directory exist
hFind = FindFirstFile(pwszTempDest, & wfd);
// If destination directory doesn't exist, create one.
if (hFind == INVALID_HANDLE_VALUE)
{
result = ::CreateDirectory(pwszTempDest,NULL);
}
else if ( ! (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
result = ::CreateDirectory(pwszTempDest,NULL);
}
// if create direcotry failed, return
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Create Direcotry failed: %s.\r\n " ),pwszTempDest));
FindClose(hFind);
return result;
}
FindClose(hFind);
// Verify source path whether is a file
// If it's a file, copy the file to destination directory and return.
hFind = FindFirstFile(pwszTempSource, & wfd);
if (INVALID_HANDLE_VALUE == hFind) // source path is not a file or directory
{
RETAILMSG( 1 , (TEXT( " Source Path is not corret: %s\r\n " ),pwszTempSource));
FindClose(hFind);
}
else if ( ! (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // it's a file
{
StringCchPrintf(pwszDestFullPath,MAX_LENGTH,L " %s\\%s " ,pwszTempDest,wfd.cFileName);
result = ::CopyFile(pwszTempSource,pwszDestFullPath,FALSE);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Copy File Failed:\r\n " )));
RETAILMSG( 1 , (TEXT( " The Source File is: %s.\r\n " ),pwszTempSource));
RETAILMSG( 1 , (TEXT( " The Dest File is: %s.\r\n " ),pwszTempDest));
}
FindClose(hFind);
return result;
}
FindClose(hFind);
// The source path is a directory, list all the sub files and directories
wcscat(pwszTempSource,L " \\* " );
hFind = FindFirstFile(pwszTempSource, & wfd);
if (INVALID_HANDLE_VALUE != hFind)
{
do
{
StringCchPrintf(pwszSourceFullPath,MAX_LENGTH,L " %s\\%s " ,pwszSourceDirectory,wfd.cFileName);
StringCchPrintf(pwszDestFullPath,MAX_LENGTH,L " %s\\%s " ,pwszTempDest,wfd.cFileName);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // Sub direcotry
{
if ((wcscmp(wfd.cFileName,L " . " ) != 0 ) && (wcscmp(wfd.cFileName,L " .. " ) != 0 ))
{
result = CopyToDirecotry(pwszSourceFullPath,pwszDestFullPath);
}
}
else // it's a file
{
result = ::CopyFile(pwszSourceFullPath,pwszDestFullPath,FALSE);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Copy File Failed:\r\n " )));
RETAILMSG( 1 , (TEXT( " The Source File is: %s.\r\n " ),pwszSourceFullPath));
RETAILMSG( 1 , (TEXT( " The Dest File is: %s.\r\n " ),pwszDestFullPath));
}
}
}
while (FindNextFile(hFind, & wfd));
}
else
{
RETAILMSG( 1 , (TEXT( " Find First File failed in source: %s.\r\n " ),pwszTempSource));
result = FALSE;
}
FindClose(hFind);
return TRUE;
}
// ---Copy source direcotry to destination directory
// ---Copy source files to destination directory
BOOL CopyToDirecotry(WCHAR * pwszSourceDirectory,WCHAR * pwszDestDirectory)
{
BOOL result = TRUE;
WCHAR pwszSourceFullPath[MAX_LENGTH] = { 0 }; // each searched source full path
WCHAR pwszDestFullPath[MAX_LENGTH] = { 0 }; // each dest full path according to the source path
WCHAR pwszTempSource[MAX_LENGTH] = { 0 };
WCHAR pwszTempDest[MAX_LENGTH] = { 0 };
WIN32_FIND_DATA wfd;
HANDLE hFind = NULL;
// pwszTempSource represents the folders or files under the current source path
wcscpy(pwszTempSource,pwszSourceDirectory);
// pwszTempDest: concrete dest file or directory full path
wcscpy(pwszTempDest,pwszDestDirectory);
// Verify whether the destination directory exist
hFind = FindFirstFile(pwszTempDest, & wfd);
// If destination directory doesn't exist, create one.
if (hFind == INVALID_HANDLE_VALUE)
{
result = ::CreateDirectory(pwszTempDest,NULL);
}
else if ( ! (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
result = ::CreateDirectory(pwszTempDest,NULL);
}
// if create direcotry failed, return
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Create Direcotry failed: %s.\r\n " ),pwszTempDest));
FindClose(hFind);
return result;
}
FindClose(hFind);
// Verify source path whether is a file
// If it's a file, copy the file to destination directory and return.
hFind = FindFirstFile(pwszTempSource, & wfd);
if (INVALID_HANDLE_VALUE == hFind) // source path is not a file or directory
{
RETAILMSG( 1 , (TEXT( " Source Path is not corret: %s\r\n " ),pwszTempSource));
FindClose(hFind);
}
else if ( ! (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // it's a file
{
StringCchPrintf(pwszDestFullPath,MAX_LENGTH,L " %s\\%s " ,pwszTempDest,wfd.cFileName);
result = ::CopyFile(pwszTempSource,pwszDestFullPath,FALSE);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Copy File Failed:\r\n " )));
RETAILMSG( 1 , (TEXT( " The Source File is: %s.\r\n " ),pwszTempSource));
RETAILMSG( 1 , (TEXT( " The Dest File is: %s.\r\n " ),pwszTempDest));
}
FindClose(hFind);
return result;
}
FindClose(hFind);
// The source path is a directory, list all the sub files and directories
wcscat(pwszTempSource,L " \\* " );
hFind = FindFirstFile(pwszTempSource, & wfd);
if (INVALID_HANDLE_VALUE != hFind)
{
do
{
StringCchPrintf(pwszSourceFullPath,MAX_LENGTH,L " %s\\%s " ,pwszSourceDirectory,wfd.cFileName);
StringCchPrintf(pwszDestFullPath,MAX_LENGTH,L " %s\\%s " ,pwszTempDest,wfd.cFileName);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // Sub direcotry
{
if ((wcscmp(wfd.cFileName,L " . " ) != 0 ) && (wcscmp(wfd.cFileName,L " .. " ) != 0 ))
{
result = CopyToDirecotry(pwszSourceFullPath,pwszDestFullPath);
}
}
else // it's a file
{
result = ::CopyFile(pwszSourceFullPath,pwszDestFullPath,FALSE);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Copy File Failed:\r\n " )));
RETAILMSG( 1 , (TEXT( " The Source File is: %s.\r\n " ),pwszSourceFullPath));
RETAILMSG( 1 , (TEXT( " The Dest File is: %s.\r\n " ),pwszDestFullPath));
}
}
}
while (FindNextFile(hFind, & wfd));
}
else
{
RETAILMSG( 1 , (TEXT( " Find First File failed in source: %s.\r\n " ),pwszTempSource));
result = FALSE;
}
FindClose(hFind);
return TRUE;
}
2. 删除文件或者目录
遍历调用方法类似,直接上Code。
代码
//
Remove file or directory
BOOL RemoveFiles(WCHAR * pwszSource)
{
// Verify the input parameter whether is NULL
if (NULL == pwszSource)
{
return FALSE;
}
WCHAR pwszTempDest[MAX_LENGTH] = { 0 };
WCHAR pwszSourceFullPath[MAX_LENGTH] = { 0 };
WIN32_FIND_DATA wfd;
HANDLE hFind = NULL;
BOOL result = FALSE;
// pwszTempDest = pwszSource
wcscpy(pwszTempDest,pwszSource);
hFind = FindFirstFile(pwszTempDest, & wfd);
if (INVALID_HANDLE_VALUE == hFind) // source path is not a file or directory
{
RETAILMSG( 1 , (TEXT( " Can't find the file or directory: %s.\r\n " ),pwszTempDest));
FindClose(hFind);
return FALSE;
}
if ( ! (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // source path is a file
{
// invoke windows API to delete file
result = ::DeleteFile(pwszTempDest);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Delete File Failed: %s.\r\n " ),pwszTempDest));
}
else
{
RETAILMSG( 1 , (TEXT( " File delted success: %s.\r\n " ),pwszTempDest));
}
FindClose(hFind);
return result;
}
else // source path is a directory
{
wcscat(pwszTempDest,L " \\* " ); // sub files and direcotries
hFind = FindFirstFile(pwszTempDest, & wfd);
if (INVALID_HANDLE_VALUE != hFind)
{
do
{
StringCchPrintf(pwszSourceFullPath,MAX_LENGTH,L " %s\\%s " ,pwszSource,wfd.cFileName);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // sub directory, recurive invoke
{
if ((wcscmp(wfd.cFileName,L " . " ) != 0 ) && (wcscmp(wfd.cFileName,L " .. " ) != 0 ))
{
result = RemoveFiles(pwszSourceFullPath);
}
}
else // it's a file, delte the file
{
result = ::DeleteFile(pwszSourceFullPath);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Delete File Failed: %s.\r\n " ),pwszSourceFullPath));
}
else
{
RETAILMSG( 1 , (TEXT( " File delted success: %s.\r\n " ),pwszSourceFullPath));
}
}
}
while (FindNextFile(hFind, & wfd));
}
}
FindClose(hFind);
// remove the empty directory
result = ::RemoveDirectory(pwszSource);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Remove Direcotry failed %s.\r\n " ),pwszSource));
}
else
{
RETAILMSG( 1 , (TEXT( " Remove Direcotry Success %s.\r\n " ),pwszSource));
}
return result;
}
BOOL RemoveFiles(WCHAR * pwszSource)
{
// Verify the input parameter whether is NULL
if (NULL == pwszSource)
{
return FALSE;
}
WCHAR pwszTempDest[MAX_LENGTH] = { 0 };
WCHAR pwszSourceFullPath[MAX_LENGTH] = { 0 };
WIN32_FIND_DATA wfd;
HANDLE hFind = NULL;
BOOL result = FALSE;
// pwszTempDest = pwszSource
wcscpy(pwszTempDest,pwszSource);
hFind = FindFirstFile(pwszTempDest, & wfd);
if (INVALID_HANDLE_VALUE == hFind) // source path is not a file or directory
{
RETAILMSG( 1 , (TEXT( " Can't find the file or directory: %s.\r\n " ),pwszTempDest));
FindClose(hFind);
return FALSE;
}
if ( ! (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // source path is a file
{
// invoke windows API to delete file
result = ::DeleteFile(pwszTempDest);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Delete File Failed: %s.\r\n " ),pwszTempDest));
}
else
{
RETAILMSG( 1 , (TEXT( " File delted success: %s.\r\n " ),pwszTempDest));
}
FindClose(hFind);
return result;
}
else // source path is a directory
{
wcscat(pwszTempDest,L " \\* " ); // sub files and direcotries
hFind = FindFirstFile(pwszTempDest, & wfd);
if (INVALID_HANDLE_VALUE != hFind)
{
do
{
StringCchPrintf(pwszSourceFullPath,MAX_LENGTH,L " %s\\%s " ,pwszSource,wfd.cFileName);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // sub directory, recurive invoke
{
if ((wcscmp(wfd.cFileName,L " . " ) != 0 ) && (wcscmp(wfd.cFileName,L " .. " ) != 0 ))
{
result = RemoveFiles(pwszSourceFullPath);
}
}
else // it's a file, delte the file
{
result = ::DeleteFile(pwszSourceFullPath);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Delete File Failed: %s.\r\n " ),pwszSourceFullPath));
}
else
{
RETAILMSG( 1 , (TEXT( " File delted success: %s.\r\n " ),pwszSourceFullPath));
}
}
}
while (FindNextFile(hFind, & wfd));
}
}
FindClose(hFind);
// remove the empty directory
result = ::RemoveDirectory(pwszSource);
if ( ! result)
{
RETAILMSG( 1 , (TEXT( " Remove Direcotry failed %s.\r\n " ),pwszSource));
}
else
{
RETAILMSG( 1 , (TEXT( " Remove Direcotry Success %s.\r\n " ),pwszSource));
}
return result;
}