实验五复制文件.docx
《实验五复制文件.docx》由会员分享,可在线阅读,更多相关《实验五复制文件.docx(21页珍藏版)》请在冰豆网上搜索。
实验五复制文件
实验五:
复制文件
一、实验目的
熟悉UNIX和Linux文件系统提供的有关文件操作的系统调用。
文件系统是使用计算机信息系统的重要接口。
通过使用文件系统的系统调用命令操作文件,以达到对文件系统实现功能的理解和掌握。
了解在Windows中,文件系统如何管理保存在磁盘、光盘等存储介质上的信息。
并通过文件系统提供的各种API,对文件进行同步和异步读写,深入理解Windows文件系统的功能和作用以及同步I/O和异步I/O的特点。
这里引入文件映射对象、命名管道和邮件槽的概念,加深对文件系统的一些先进技术的深入理解。
二、程序设计与实现
Linux下:
1、文件复制函数
voidCopyFile(char*fsource,char*ftarget){
intfd=open(fsource,0);//打开文件,文件描述符
fdr=creat(ftarget,statbuf.st_mode);
…
totals++;//totals是全局变量,统计总共复制的文件数
while((wordbit=read(fd,BUFFER,1024))>0)//读取源文件字节数>0
{
write(fdr,BUFFER,wordbit);//写入目标文件
}
timeby.actime=statbuf.st_atime;//修改文件的时间信息
timeby.modtime=statbuf.st_mtime;
close(fd);//关闭文件
close(fdr);
}
2、复制源目录
voidMycp(char*fsource,char*ftarget){
/*初始化相关变量*/
dir=opendir(source);//打开目录,返回指向DIR结构的指针
while((entry=readdir(dir))!
=NULL)//读目录
{
if(strcmp(entry->d_name,".")==0||strcmp(entry->d_name,"..")==0)//判断目录
continue;
}
if(entry->d_type==4){
/*参数修改*/
stat(source,&statbuf);//统计文件属性信息
mkdir(target,statbuf.st_mode);//创建目标目录
timeby.actime=statbuf.st_atime;
timeby.modtime=statbuf.st_mtime;//修改文件存取和修改时间
utime(target,&timeby);
Mycp(source,target);
}
else//没有子目录,直接复制
{/*参数修改*/
CopyFile(source,target);//调用文件复制函数
}
}
3、遍历源目录
voidwalkdir(char*dir,char*dedir,intdepth)
{
if((dp=opendir(dir))==NULL)/*打开文件出错报错*/
if((dedp=opendir(dedir))==NULL)/*目标目录不存在创建目标目录
*/
{
mkdir(dedir,statbuf.st_mode);//创建目录
timeby.actime=statbuf.st_atime;//修改时间属性,存取时间
timeby.modtime=statbuf.st_mtime;//修改时间
utime(dedir,&timeby);
}
Mycp(dir,dedir);//开始复制
}
4、main函数—接受源目录和目标目录
intmain(intargc,char*argv[])
{
if(argc<2){printf("needtwoparameters!
\n");}
/*输入参数不足报错*/
}
Windows下:
1、main函数
检查是否传递两个目录给程序,传递目录成功则开始遍历目录,否则报错退出
if(argc!
=3)
{
printf("ARGCERROR!
\n");//参数出错
return-1;
}else
{
walkdir(argv[1],argv[2]);//查找目录
}
2、walkdir函数
检查是否打开源目录,失败则报错退出,成功则检查是否已存在目标目录,不存在则创建该目录。
两项检查完毕后进行复制操作。
if(FindFirstFile(sodir,&lpfindfiledata)==INVALID_HANDLE_VALUE)
{
printf("SourceFolderdoesnotexist!
\n");//查找源文件路径失败
}
if(FindFirstFile(dedir,&lpfindfiledata)==INVALID_HANDLE_VALUE)
{
//当目标目录不存在时,创建该目录
CreateFileD(sodir,dedir);
}
Mycp(sodir,dedir);//复制
3、Mycp函数,复制源目录信息
voidMycp(char*fsource,char*ftarget)//将源目录信息复制到目标目录下
if(hfind!
=INVALID_HANDLE_VALUE)//句柄是否有效
{
while(FindNextFile(hfind,&lpfindfiledata)!
=0)//循环找文件
{
if((strcmp(lpfindfiledata.cFileName,".")!
=0)&&(strcmp(lpfindfiledata.cFileName,"..")!
=0))//是否是目录
{
if((strcmp(lpfindfiledata.cFileName,".")!
=0)&&(strcmp(lpfindfiledata.cFileName,"..")!
=0))//是否存在该目录
{
/*文件名的字符串处理*/
CreateFileD(source,target);//创建目录
Mycp(source,target);//递归进入子目录复制
}
}
else{
/*文件名的字符串处理*/
CopyFile(source,target);//直接复制文件
}
}
}
4、CopyFile函数
复制文件并统计复制的文件数
voidCopyFile(char*fsource,char*ftarget)
totals++;//统计复制的文件数
/*处理句柄信息,查找路径*/
int*BUFFER=newint[size];//新开缓冲区,保存数据
ReadFile(hsource,BUFFER,size,&wordbit,NULL);//源文件读数据
WriteFile(htarget,BUFFER,size,&wordbit,NULL);//目标文件写数据
/*关闭句柄和文件*/
三、实验代码如下:
1.Windows下:
//复制文件.cpp:
定义控制台应用程序的入口点。
//
#include"stdafx.h"
//windowscopyfile
/*API
CreateFile(),ReadFile(),WriteFile(),CloseHandle()..soon
*/
#include
#include
#include
#include
#include
voidMycp(char*fsource,char*ftarget);//将源目录信息复制到目标目录下
voidCopyFile(char*fsource,char*ftarget);//
BOOLGetDirectoryTime(char*DirectoryName,FILETIME*lpCreationTime,FILETIME*lpLastAccessTime,FILETIME*lpLastWriteTime);//得到时间信息
BOOLSetDirectoryTime(char*DirectoryName,FILETIMElpCreationTime,FILETIMElpLastAccessTime,FILETIMElpLastWriteTime);//设置时间信息
intCreateFileD(char*source,char*target);//为目标文件创建目录并保持和源文件相同的属性
intmain(intargc,char*argv[])
{
WIN32_FIND_DATAlpfindfiledata;
/*
typedefstruct_WIN32_FIND_DATA{
DWORDdwFileAttributes;//文件属性
FILETIMEftCreationTime;//文件创建时间
FILETIMEftLastAccessTime;//文件最后一次访问时间
FILETIMEftLastWriteTime;//文件最后一次修改时间
DWORDnFileSizeHigh;//文件长度高32位
DWORDnFileSizeLow;//文件长度低32位
DWORDdwReserved0;//系统保留
DWORDdwReserved1;//系统保留
TCHARcFileName[MAX_PATH];//长文件名
TCHARcAlternateFileName[14];//8.3格式文件名
}WIN32_FIND_DATA,*PWIN32_FIND_DATA;
*/
if(argc!
=3)
{
printf("ARGCERROR!
\n");//参数出错
}
else
{
/*查找指定文件路径的文件
FindFirstFile
HANDLEFindFirstFile(
LPCTSTRlpFileName,//filename
LPWIN32_FIND_DATAlpFindFileData//databuffer
);
调用成功返回一个句柄;
调用失败返回为INVALID_HANDLE_VALUE
*/
if(FindFirstFile(argv[1],&lpfindfiledata)==INVALID_HANDLE_VALUE)
{
printf("SourceFolderdoesnotexist!
\n");//查找源文件路径失败
}
if(FindFirstFile(argv[2],&lpfindfiledata)==INVALID_HANDLE_VALUE)
{
//argv[2]目标文件
CreateFileD(argv[1],argv[2]);
}
Mycp(argv[1],argv[2]);//复制
}
printf("CopyFinished!
\n");
return0;
}
intCreateFileD(char*source,char*target)
{
FILETIMElpCreationTime;//创建时间
FILETIMElpLastAccessTime;//最近一次访问时间
FILETIMElpLastWriteTime;//最近一次修改时间
//创建目录
/*
BOOLCreateDirectory(
LPCTSTRlpPathName,//新创建目录的路径名
LPSECURITY_ATTRIBUTESlpSecurityAttributes//安全属性
);
*/
intappendix=CreateDirectory(target,NULL);
GetDirectoryTime(source,&lpCreationTime,&lpLastAccessTime,&lpLastWriteTime);
SetDirectoryTime(target,lpCreationTime,lpLastAccessTime,lpLastWriteTime);
returnappendix;
}
BOOLGetDirectoryTime(char*DirectoryName,FILETIME*lpCreationTime,FILETIME*lpLastAccessTime,FILETIME*lpLastWriteTime)
{
//获取文件夹时间属性信息
HANDLEhDirectory=CreateFile(DirectoryName,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
/*CreateFile,可打开或创建以下对象,并返回可访问的句柄
HANDLEWINAPICreateFile(
_In_LPCTSTRlpFileName,
_In_DWORDdwDesiredAccess,访问方式
_In_DWORDdwShareMode,共享
_In_opt_LPSECURITY_ATTRIBUTESlpSecurityAttributes,安全属性
_In_DWORDdwCreationDisposition,OPEN_EXISTING文件必须已经存在
_In_DWORDdwFlagsAndAttributes,指示系统为文件的打开或创建执行一个备份或恢复操作.系统保证调用进程忽略文件的安全选项
_In_opt_HANDLEhTemplateFile
);
*/
BOOLretval=GetFileTime(hDirectory,lpCreationTime,lpLastAccessTime,lpLastWriteTime);
CloseHandle(hDirectory);//关闭文件夹
returnretval;
}
BOOLSetDirectoryTime(char*DirectoryName,FILETIMElpCreationTime,FILETIMElpLastAccessTime,FILETIMElpLastWriteTime)
{
//设置文件夹时间属性
HANDLEhDirectory=CreateFile(DirectoryName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
BOOLretval=SetFileTime(hDirectory,&lpCreationTime,&lpLastAccessTime,&lpLastWriteTime);
CloseHandle(hDirectory);
returnretval;
}
voidCopyFile(char*fsource,char*ftarget)
{
WIN32_FIND_DATAlpfindfiledata;
HANDLEhfind=FindFirstFile(fsource,&lpfindfiledata);//查找指定文件路径
HANDLEhsource=CreateFile(fsource,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,/*文件若存在则打开*/FILE_ATTRIBUTE_NORMAL,NULL);
HANDLEhtarget=CreateFile(ftarget,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,/*创建一个文件*/FILE_ATTRIBUTE_NORMAL/*不设置属性*/,NULL);
LONGsize=lpfindfiledata.nFileSizeLow-lpfindfiledata.nFileSizeHigh;//length
DWORDwordbit;
int*BUFFER=newint[size];//新开缓冲区,保存数据
ReadFile(hsource,BUFFER,size,&wordbit,NULL);//源文件读数据
/*
BOOLReadFile(
HANDLEhFile,//文件的句柄
LPVOIDlpBuffer,//保存读入数据的一个缓冲区
DWORDnNumberOfBytesToRead,//读入的字节数
LPDWORDlpNumberOfBytesRead,//指向实际读取字节数的指针
LPOVERLAPPEDlpOverlapped//如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。
//该结构定义了一次异步读取操作。
否则,应将这个参数设为NULL
);
*/
/*
WriteFile函数原型与CreateFile相同
*/
WriteFile(htarget,BUFFER,size,&wordbit,NULL);//目标文件写数据
//修改文件时间信息
/*SetFileTime
参数类型及说明
hFileLong,系统文件句柄
lpCreationTimeFILETIME,文件的创建时间
lpLastAccessTimeFILETIME,文件上一次访问的时间
lpLastWriteTimeFILETIME,文件最近一次修改的时间
*/
//GetFileTime(hsource,&lpfindfiledata.ftCreationTime,&lpfindfiledata.ftLastAccessTime,&lpfindfiledata.ftLastWriteTime);
//SetFileTime(htarget,&lpfindfiledata.ftCreationTime,&lpfindfiledata.ftLastAccessTime,&lpfindfiledata.ftLastWriteTime);
CloseHandle(hfind);//关闭句柄
CloseHandle(hsource);
CloseHandle(htarget);
}
voidMycp(char*fsource,char*ftarget)//将源目录信息复制到目标目录下
{
WIN32_FIND_DATAlpfindfiledata;
charsource[512];
chartarget[512];
strcpy(source,fsource);//copysource->fsource
strcpy(target,ftarget);
strcat(source,"\\*.*");
strcat(target,"\\");
HANDLEhfind=FindFirstFile(source,&lpfindfiledata);
if(hfind!
=INVALID_HANDLE_VALUE)
{
while(FindNextFile(hfind,&lpfindfiledata)!
=0)//查找下一个文件成功/*FindNextFile根据指定的一个文件名查找下一个文件
BOOLFindNextFile(
HANDLEhFindFile,//searchhandle
LPWIN32_FIND_DATAlpFindFileData//databuffer
);
*/
{
if(lpfindfiledata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)//判断目录
{
if((strcmp(lpfindfiledata.cFileName,".")!
=0)&&(strcmp(lpfindfiledata.cFileName,"..")!
=0))
{
memset(source,'0',sizeof(source));
strcpy(source,fsource);
strcat(source,"\\");
strcat(source,lpfindfiledata.cFileName);//追加文件strcat(target,lpfindfiledata.cFileName);
CreateFileD(source,target);
Mycp(source,target);//进入子目录复制
strcpy(source,fsource);
strcat(source,"\\");
strcpy(target,ftarget);
strcat(target,"\\");
}
}
else//无目录
{
//直接复制
memset(source,'0',sizeof(source));
strcpy(source,fsource);
strcat(source,"\\");
strcat(source,lpfindfiledata.cFileName);
strcat(target,lpfindfiledata.cFileName);
CopyFile(source,target);
strcpy(source,fsource);
strcat(source,"\\");
strcpy(target,ftarget);
strcat(target,"\\");
}
}
}
}
2.Linux下代码:
#include
#include
#include