您的位置:首页 > 电脑网络 > 电脑配件 > vc实现copy命令

vc实现copy命令

luyued 发布于 2011-04-20 22:25   浏览 N 次  

编写window下的copy命令,要求不仅能够实现单个文件的复制,而且要求还能实现文件夹递归复制,刚开始做这个题的时候着实让我纠结了好半天,做为一个C语言的菜鸟,做这种题实在是太伤脑筋,不过好在本人有知难而上的好精神(嘿嘿,自恋一把),在经过将近一天的努力下,终于做出来了这个命令,个人觉得好东西就应该给大家一起分享,所以特贴出源码如下,希望对一些和我一样是C语言菜鸟的同鞋有所帮助呵

首先要说明,本源码全部使用window的底层接口实现,这对于那些只知道使用C高级接口的同鞋来说,看起来可能会有些晦涩难懂,不过不要紧,我会尽量给大家多一些的注释,帮助大家做到深入理解

#include
#include
#include
#include
#include
#include


//定义一些常量
#define MAX_PATH 260
#define BUF_SIZE 0x200
#define DIRNAME_LEN MAX_PATH+2
#define TYPE_FILE 1
#define TYPE_DIR 2
#define TYPE_DOT 3

//定义函数,用于完成文件类型的确定
static DWORD FileType (LPWIN32_FIND_DATA pFileData);
//定义函数,用于完成文件夹的递归复制
static BOOL CopyDirectory (LPTSTR,LPTSTR,BOOL);
//定义函数,用于完成单个文件的复制,由CopyDirectory调用,辅助其完成文件夹的递归复制
static BOOL CopyOneFile (LPTSTR,LPTSTR,LPTSTR,BOOL);
//定义函数,用于完成单个文件的复制
static BOOL CopyOneFile2 (LPTSTR,LPTSTR,BOOL);
//将文件由输入流输出到输出流
static VOID CatFile (HANDLE, HANDLE, BOOL);
//截取路径,以获得文件名
static TCHAR* getLastName(LPTSTR);
//打印帮助信息
static VOID PrintHelp();

int _tmain (int argc, LPTSTR argv [])
{
DWORD i,s = 0,d = 0;
BOOL isKeepTime = 0;
BOOL isDir = 0;
//分析用户dos输入的参数,以确定要完成的功能
for(i = 1;i < argc;i++)
{
//如果有-r开头,则是文件夹的复制
if(argv[i][0] == '-' && argv[i][1]=='r')
{
isDir = 1;
}
//如果有-p开头,则要求复制的时候保存原文件的修改时间,否则新文件的修改时间为系统当前时间
else if(argv[i][0] == '-' && argv[i][1]=='p')
{
isKeepTime = 1;
}
//如果有-h开头,则打印帮助信息
else if(argv[i][0] == '-' && argv[i][1]=='h')
{
PrintHelp();
return 0;
}
//如果还有别的开头,说明用户是非法操作,打印帮助信息,提醒用户应该的操作
else if(argv[i][0] == '-')
{
PrintHelp();
return 0;
}
else{
if(s == 0)
s = i;
else
{
d = i;
}
}
}
//没有源文件,报错
if(s == 0)
{
_tprintf (_T ("ERROR:No source file."));
return 0;
}
//没有目标文件夹,报错
if(d == 0)
{
_tprintf (_T ("ERROR:No destination file."));
return 0;
}
if(isDir == 1)
{
TCHAR srcPath [MAX_PATH + 1];
TCHAR desPath [MAX_PATH + 1];
TCHAR* dirName;
//获得源文件和目标文件夹的路径
_tcscpy (srcPath, argv[s]);
_tcscpy (desPath, argv[d]);
_tcscat (desPath, _T("\\"));
dirName = getLastName(srcPath);
_tcscat (desPath, dirName);
CreateDirectory(desPath,NULL);
//调用文件夹复制函数,完成文件夹的复制
if(isKeepTime == 1)
CopyDirectory(argv[s],desPath,TRUE);
else
CopyDirectory(argv[s],desPath,FALSE);
}
else
{
TCHAR srcPath [MAX_PATH + 1];
TCHAR desPath [MAX_PATH + 1];
TCHAR* dirName;

_tcscpy (srcPath, argv[s]);
_tcscpy (desPath, argv[d]);
_tcscat (desPath, _T("\\"));
dirName = getLastName(srcPath);
_tcscat (desPath, dirName);
//调用单个文件复制函数完成单个文件的复制
if(isKeepTime == 1)
CopyOneFile2(argv[s],desPath,TRUE);
else
CopyOneFile2(argv[s],desPath,FALSE);
}

}


//确定文件的类型函数
static DWORD FileType (LPWIN32_FIND_DATA pFileData)
{
BOOL IsDir;
DWORD FType;
FType = TYPE_FILE;
IsDir = (pFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
if (IsDir)
if (lstrcmp (pFileData->cFileName, _T (".")) == 0
|| lstrcmp (pFileData->cFileName, _T ("..")) == 0)
FType = TYPE_DOT;
else FType = TYPE_DIR;
return FType;
}

//完成文件夹的复制
static BOOL CopyDirectory (LPTSTR PathName,LPTSTR tarPath,BOOL keepTime)
{
HANDLE SearchHandle;
WIN32_FIND_DATA FindData;
TCHAR tmpPath [MAX_PATH + 1];
DWORD FType;

_tcscpy (tmpPath, PathName);
_tcscat (tmpPath, _T("\\*"));
//实现文件夹的遍历
SearchHandle = FindFirstFile (tmpPath, &FindData);
if (SearchHandle == INVALID_HANDLE_VALUE) {
_tprintf (_T ("ERROR:The source file is not a directory."));
return FALSE;
}
do{
FType = FileType (&FindData);
if(FType == TYPE_FILE)
{
CopyOneFile(PathName,FindData.cFileName,tarPath,keepTime);
}
else if (FType == TYPE_DIR)
{
TCHAR tmpPath1 [MAX_PATH + 1];
_tcscpy (tmpPath1, tarPath);
_tcscat (tmpPath1, _T("\\"));
_tcscat (tmpPath1, FindData.cFileName);
CreateDirectory(tmpPath1,NULL);

_tcscpy (tmpPath, PathName);
_tcscat (tmpPath, _T("\\"));
_tcscat (tmpPath, FindData.cFileName);
CopyDirectory(tmpPath,tmpPath1,keepTime);
}
else
{
continue;
}

}while(FindNextFile (SearchHandle, &FindData));
FindClose (SearchHandle);
}

//完成单个文件的复制
BOOL CopyOneFile (LPTSTR srcPath,LPTSTR filename,LPTSTR desPath,BOOL keepTime)
{
TCHAR src[MAX_PATH + 1];
TCHAR des[MAX_PATH + 1];
HANDLE hInFile,hStdOut;
_tcscpy (src, srcPath);
_tcscat (src, _T("\\"));
_tcscat (src,filename);

_tcscpy (des, desPath);
_tcscat (des, _T("\\"));
_tcscat (des,filename);

_tprintf (_T ("%s-->%s\n"), src,des);
//获得源文件的句柄
hInFile = CreateFile (src, GENERIC_READ,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//获得目标文件的句柄
hStdOut = CreateFile (des, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if (hInFile == INVALID_HANDLE_VALUE)
_tprintf (_T ("ERROR:File does not exist."));
if (hInFile == INVALID_HANDLE_VALUE)
_tprintf (_T ("ERROR:Copy wrong."));
CatFile (hInFile, hStdOut, keepTime);
CloseHandle (hInFile);
CloseHandle (hStdOut);
return 0;
}
//从输入流内获取内容,并输出到输出流
static VOID CatFile (HANDLE hInFile, HANDLE hOutFile,BOOL keepTime)
{
DWORD nIn, nOut;
TCHAR s[100];
BYTE Buffer [BUF_SIZE];
FILETIME createTime;
FILETIME lastAccessTime;
FILETIME lastWriteTime;

while (ReadFile (hInFile, Buffer, BUF_SIZE, &nIn, NULL) && (nIn != 0)
&& WriteFile (hOutFile, Buffer, nIn, &nOut, NULL));

if (keepTime && GetFileTime(hInFile,&createTime,&lastAccessTime,&lastWriteTime))
{
if (!SetFileTime (hOutFile, &createTime, &lastAccessTime, &lastWriteTime))
_tprintf (_T ("ERROR:Failure setting file times."));
}
return;
}

static BOOL CopyOneFile2 (LPTSTR srcPath,LPTSTR desPath,BOOL keepTime)
{
//获取源文件的句柄
HANDLE hInFile = CreateFile (srcPath, GENERIC_READ,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//获取目标文件的句柄
HANDLE hStdOut = CreateFile (desPath, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
_tprintf (_T ("%s-->%s\n"), srcPath,desPath);
if (hInFile == INVALID_HANDLE_VALUE)
_tprintf (_T ("ERROR:File does not exist."));
if (hInFile == INVALID_HANDLE_VALUE)
_tprintf (_T ("ERROR:Copy wrong."));
CatFile (hInFile, hStdOut,keepTime);
CloseHandle (hInFile);
CloseHandle (hStdOut);
return 0;
}
//解析用户输入的文件路径,获得文件名
static TCHAR* getLastName(LPTSTR filePath)
{
TCHAR seps[] = _T("\\");
TCHAR* token = _tcstok(filePath, seps );
TCHAR* ret;
while( token != NULL )
{
ret = token;
token = _tcstok( NULL, seps);
}
return ret;
}
//实现打印函数
static VOID PrintHelp()
{
_tprintf (_T ("-r copy directory\n"));
_tprintf (_T ("-p keep create time\n"));
_tprintf (_T ("-h print this help page\n"));
}

图文资讯
广告赞助商