C实现
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0]))
//判断是否为一个目录
static BOOL IsChildDir(WIN32_FIND_DATA *lpFindData)
{
return ((lpFindData->dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY) != 0) &&
(lstrcmp(lpFindData->cFileName, __TEXT(".")) != 0) &&
(lstrcmp(lpFindData->cFileName, __TEXT("..")) != 0);
}
//查找下一个目录
static BOOL FindNextChildDir(HANDLE hFindFile, WIN32_FIND_DATA *lpFindData)
{
BOOL fFound = FALSE;
do
{
fFound = FindNextFile(hFindFile, lpFindData);
}
while (fFound && !IsChildDir(lpFindData));
return fFound;
}
//查找第一个子目录
static HANDLE FindFirstChildDir(LPTSTR szPath, WIN32_FIND_DATA *lpFindData)
{
BOOL fFound;
HANDLE hFindFile = FindFirstFile(szPath, lpFindData);
if (hFindFile != INVALID_HANDLE_VALUE)
{
fFound = IsChildDir(lpFindData);
if (!fFound)
{
fFound = FindNextChildDir(hFindFile, lpFindData);
}
if (!fFound)
{
FindClose(hFindFile);
hFindFile = INVALID_HANDLE_VALUE;
}
}
return hFindFile;
}
typedef struct
{
int nDepth;
BOOL fRecurse;
TCHAR szBuf[1000];
int nIndent;
BOOL fOk;
BOOL fIsDir;
WIN32_FIND_DATA FindData;
} DIRWALKDATA, *LPDIRWALKDATA;
static void DirWalkRecurse(LPDIRWALKDATA pDW, LPTSTR pszRootPath, LPTSTR pszdestPath)
{
HANDLE hFind;
LPTSTR From;
LPTSTR To;
From = (LPTSTR)malloc(100 * sizeof(LPTSTR));
To = (LPTSTR)malloc(100 * sizeof(LPTSTR));
pDW->nDepth++;
pDW->nIndent = 3 * pDW->nDepth;
_stprintf(pDW->szBuf, __TEXT("%*s"), pDW->nIndent, __TEXT(""));
GetCurrentDirectory(chDIMOF(pDW->szBuf) - pDW->nIndent, & pDW->szBuf[pDW->nIndent]);
hFind = FindFirstFile(__TEXT("*.*"), & pDW->FindData);
pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
while (pDW->fOk)
{
pDW->fIsDir = pDW->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
if (!pDW->fIsDir ||
(!pDW->fRecurse && IsChildDir(&pDW->FindData)))
{
_stprintf(pDW->szBuf,
pDW->fIsDir ? __TEXT("%*s[%s]") : __TEXT("%*s%s"),
pDW->nIndent, __TEXT(""),
pDW->FindData.cFileName);
lstrcpy(From, pszRootPath);
lstrcat(From, "\\");
lstrcat(From, pDW->FindData.cFileName);
lstrcpy(To, pszdestPath);
lstrcat(To, "\\");
lstrcat(To, pDW->FindData.cFileName);
HANDLE hfile = CreateFile(
To,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS,
pDW->FindData.dwFileAttributes,
NULL);
HANDLE dfile = CreateFile(
From,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
pDW->FindData.dwFileAttributes,
NULL);
DWORD filesize = GetFileSize(dfile, NULL);
char *buffer = new char[filesize + 1];
DWORD readsize;
ReadFile(dfile, buffer, filesize, & readsize, NULL);
WriteFile(hfile, buffer, filesize, & readsize, NULL);
buffer[filesize] = 0;
CloseHandle(hfile);
CloseHandle(dfile);
}
else if (pDW->fIsDir && IsChildDir(&pDW->FindData))
{
SECURITY_ATTRIBUTES attribute;
attribute.nLength = sizeof(attribute);
attribute.lpSecurityDescriptor = NULL;
attribute.bInheritHandle = FALSE;
SetCurrentDirectory(pszdestPath);
CreateDirectory(
pDW->FindData.cFileName,
& attribute
);
SetCurrentDirectory(pszRootPath);
}
pDW->fOk = FindNextFile(hFind, & pDW->FindData);
}
if (hFind != INVALID_HANDLE_VALUE)
{
FindClose(hFind);
}
if (pDW->fRecurse)
{
hFind = FindFirstChildDir(__TEXT("*.*"), & pDW->FindData);
pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
while (pDW->fOk)
{
if (SetCurrentDirectory(pDW->FindData.cFileName))
{
lstrcpy(From, pszRootPath);
lstrcat(From, "\\");
lstrcat(From, pDW->FindData.cFileName);
lstrcpy(To, pszdestPath);
lstrcat(To, "\\");
lstrcat(To, pDW->FindData.cFileName);
DirWalkRecurse(pDW, From, To);
SetCurrentDirectory(__TEXT(".."));
}
pDW->fOk = FindNextChildDir(hFind, & pDW->FindData);
}
if (hFind != INVALID_HANDLE_VALUE)
{
FindClose(hFind);
}
}
pDW->nDepth--;
}
void DirWalk(LPTSTR pszRootPath, LPTSTR pszdestPath, BOOL fResourse)
{
TCHAR szCurrDir[_MAX_DIR];
DIRWALKDATA DW;
GetCurrentDirectory(chDIMOF(szCurrDir), szCurrDir);
SetCurrentDirectory(pszRootPath);
DW.nDepth = - 1;
DW.fRecurse = fResourse;
DirWalkRecurse(&DW, pszRootPath, pszdestPath);
SetCurrentDirectory(szCurrDir);
}
int main(int argc, char *argv[])
{
char From[100], To[100];
int i;
if (argc != 3)
{
printf("Error\n");
exit(0);
}
strcpy(From, argv[1]);
if (strlen(From) != 1 && From[strlen(From) - 1] == '\\')
From[strlen(From) - 1] = 0;
for (i = strlen(From); i >= 0; i--)
if (From[i] == '\\')
break;
WIN32_FIND_DATA findData;
FindFirstFile(argv[2], & findData);
strcpy(To, argv[2]);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
printf("文件夹%s已存在,直接复制\n", To);
}
else
{
printf("文件夹%s不存在,新建一个\n", To);
CreateDirectory(argv[2], NULL);
}
if (strcmp(&From[i + 1], "") && strcmp(&From[i + 1], "..") && strcmp(&From[i + 1], "."))
{
if (To[strlen(To) - 1] != '\\')
strcat(To, "/");
SetCurrentDirectory(argv[2]);
}
DirWalk((char *)argv[1], (char *)To, TRUE);
printf("复制成功\n");
return 0;
}