复制文件实验报告.docx
- 文档编号:7103598
- 上传时间:2023-01-17
- 格式:DOCX
- 页数:11
- 大小:134.39KB
复制文件实验报告.docx
《复制文件实验报告.docx》由会员分享,可在线阅读,更多相关《复制文件实验报告.docx(11页珍藏版)》请在冰豆网上搜索。
复制文件实验报告复制文件实验报告实验五复制文件一、实验目的了解在Windows和Linux系统中,文件系统是如何管理在磁盘、光盘等存储介质上的信息,并通过文件系统提供的各种API,对文件进行同步和异步读写,深入理解Windows和Linux文件系统的功能和作用以及同步I/O和异步I/O的特点。
二、实验内容完成一个目录复制命令mycp,包括目录下的文件和子目录。
说明:
分别在Windows和Linux平台上做。
Linuk:
mkdir,opendir,readdir,symlink,readlink等系统调用Windows:
CreateDirectory,FindFirstFile,FindNextFile等函数三、程序设计与实现在Windows下实现(详见代码):
1、程序中使用的结构体
(1)在调用函数FindFirstFile、FindNextFile时,将找到的文件的信息存储在win32_FIND_DATA结构体中。
typedefstruct_WIN32_FIND_DATADWORDdwFileAttributes;/文件属性FILETIMEftCreationTime;/文件创建时间FILETIMEftLastAccessTime;/文件最后一次访问时间FILETIMEftLastWriteTime;/文件最后一次修改时间DWORDnFileSizeHigh;/文件长度高32位DWORDnFileSizeLow;/文件长度低32位DWORDdwReserved0;/系统保留DWORDdwReserved1;/系统保留TCHARcFileNameMAX_PATH;/长文件名TCHARcAlternateFileName14;/8.3格式文件名WIN32_FIND_DATA,*PWIN32_FIND_DATA,*LPWIN32_FIND_DATA;
(2)FILETIME结构体用来记录文件时间,该结构是表示100纳秒间隔数为64位值从1601年一月1日。
typedefstruct_FILETIMEDWORDdwLowDateTime;/低32位DWORDdwHighDateTime;/高32位FILETIME,*PFILETIME,*LPFILETIME;2、程序中使用的函数
(1)FindFirstFile()函数作用:
查找指定文件路径的文件调用格式:
HANDLEWINAPIFindFirstFile(LPCTSTRlpFileName,/文件名LPWIN32_FIND_DATAlpFindFileData/数据缓冲区);说明:
调用成功返回非0,否则返回0。
注意:
lpFileName指向一个以0结尾的字符串的字符串的文件名,文件名可以包含通配符(*和?
)。
(2)FindNextFile()函数作用:
查找FindFirstFile()函数搜索后的下一个文件调用格式:
BOOLWINAPIFindNextFile(HANDLEhFindFile,/FindFirstFile返回的文件句柄LPWIN32_FIND_DATAlpFindFileData/win32_FIND_DATA结构的地址);说明:
调用成功返回非0,失败为0。
(3)CreateFile()函数作用:
创建或打开文件调用格式:
HANDLEWINAPICreateFile(LPCTSTRlpFileName,/文件名字DWORDdwDesiredAccess,/指定对象的访问类型DWORDdwShareMode,/共享文件的方式LPSECURITY_ATTRIBUTESlpSecurityAttributes,/安全属性DWORDdwCreationDisposition,/创建文件方式DWORDdwFlagsAndAttributes,/指定文件的属性和标志HANDLEhTemplateFile/模板文件);说明:
调用成功返回为只想指定文件的打开句柄,失败返回值为INVALID_HANDLE_VALUE。
(4)ReadFile()函数作用:
从文件中读数据调用格式:
BOOLWINAPIReadFile(HANDLEhFile,/要读取的文件LPVOIDlpBuffer,/缓冲区DWORDnNumberOfBytesToRead,/缓冲区容量LPDWORDlpNumberOfBytesRead,/实际读的字节数LPOVERLAPPEDlpOverlapped/I/O方式);说明:
调用成功返回非0,失败为0。
该函数从文件指针指示的位置读数据,在读操作完成后,文件指针用实际读的字节数进行调整。
(5)WriteFile()函数作用:
向文件中写数据调用格式:
BOOLWINAPIWriteFile(HANDLEhFile,/要写入的文件LPCVOIDlpBuffer,/数据DWORDnNumberOfBytesToWrite,/缓冲区容量LPDWORDlpNumberOfBytesWritten,/写入的字节数LPOVERLAPPEDlpOverlapped/I/O方式);说明:
调用成功返回非0,失败为0。
该函数用来以同步或异步的方式在文件指针所指的位置把数据写入文件后,文件指针用实际写入的字节数进行调整。
(6)GetFileTime()函数作用:
获取文件的时间信息调用格式:
BOOLWINAPIGetFileTime(HANDLEhFile,/指定的文件句柄LPFILETIMElpCreationTime,/文件创建时间LPFILETIMElpLastAccessTime,/文件最近一次访问时间LPFILETIMElpLastWriteTime/文件最近一次修改时间);说明:
调用成功返回非0,失败返回0。
(7)SetFileTime()函数作用:
设置文件的时间信息调用格式:
BOOLWINAPISetFileTime(HANDLEhFile,/指定的文件句柄FILETIME*lpCreationTime,/文件创建时间FILETIME*lpLastAccessTime,/文件最近一次访问时间FILETIME*lpLastWriteTime/文件最近一次修改时间);说明:
调用成功返回非0,失败返回0。
(8)CreateDirectory()函数作用:
创建目录调用格式:
BOOLWINAPICreateDirectory(LPCTSTRlpPathName,/新创建目录的文件名LPSECURITY_ATTRIBUTESlpSecurityAttributes/安全属性);说明:
调用成功返回TRUE,失败返回FALSE。
在Linux下实现(详见代码):
1、程序中使用到的结构体
(1)记录文件相关属性的结构体statstructstatdev_tst_dev;/文件的设备编号ino_tst_ino;/节点mode_tst_mode;/文件的类型和存取的权限nlink_tst_nlink;/连到该文件的硬连接数目uid_tst_uid;/用户IDgid_tst_gid;/组IDdev_tst_rdev;/若此文件为设备文件,则为其设备编号off_tst_size;/文件字节数(文件大小)unsignedlongst_blksize;/块大小(文件系统的I/O缓冲区大小)unsignedlongst_blocks;/块数time_tst_atime;/最后一次访问时间time_tst_mtime;/最后一次修改时间time_tst_ctime;/最后一次改变时间(指属性);
(2)修改文件的存取和修改时间的结构体utimbufstructutimbuftime_tactime;/文件数据的最后存取时间time_tmodtime;/文件数据的最后修改时间
(2)存储目录中的文件信息的结构体direntstructdirentlongd_ino;/索引节点号off_td_off;/在目录文件中的偏移unsignedshortd_reclen;/文件名长unsignedchard_type;/文件类型chard_nameNAME_MAX+1;/文件名(3)存储符号链接文件的时间属性的结构体timevalstructtimeval_time_ttv_sec;/秒_suseconds_ttv_usec;/微秒;2、程序中使用的函数
(1)readlink()函数作用:
读取符号连接文件本身的信息调用格式:
intreadlink(constchar*path,char*buf,size_tbufsiz);说明:
执行成功则返回字符串的字符数,失败返回-1。
(2)symlink()函数作用:
创建符号连接文件调用格式:
intsymlink(constchar*oldpath,constchar*newpath);说明:
成功则返回0,失败返回-1。
symlink()以参数newpath指定的名称来建立一个新的连接(符号连接)到参数oldpath所指定的已存在文件。
参数oldpath指定的文件不一定要存在,如果参数newpath指定的名称为一已存在的文件则不会建立连接。
(3)stat()函数、lstat()函数作用:
统计文件属性信息调用格式:
intstat(constchar*file_name,structstat*buf);说明:
调用成功返回0,失败为-1。
当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。
(4)utime()函数作用:
修改普通文件的存取时间和更改时间调用格式:
intutime(constchar*filename,structutimbuf*buf);说明:
如果参数buf为空指针(NULL),则该文件的存取时间和更改时间全部会设为目前时间。
执行成功则返回0,失败返回-1。
(5)lutime()函数作用:
修改符号连接文件的存取时间和更改时间调用格式:
intlutimes(constchar*path,conststructtimeval*times);说明:
执行成功返回0,失败为-1。
(6)opendir()函数作用:
打开一个目录调用格式:
DIR*opendir(constchar*path);说明:
如果该函数成功运行,将返回一组目录流(一组目录字符串),如果失败将返回空指针。
(7)readdir()函数作用:
读取opendir返回值的那个列表调用格式:
structdirent*readdir(DIR*dir_handle);说明:
返回dirent结构体指针。
(8)mkdir()函数作用:
创建目录调用格式:
intmkdir(constchar*filename,mode_tmode);说明:
调用成功返回0,失败为-1。
四、实验结果及分析在Windows下实现:
1、实验截图如下:
2、实验中遇到的问题及分析一个困扰我最久的问题就是在退出文件夹时才设置文件夹的修改时间,不能在创建的时候设置目标文件夹的时间,原因是:
假如源文件夹a的最后一次修改时间为16:
18,而你在创建目标文件夹时也将时间设置为16:
18,你觉得挺好的,当你进入文件夹b,并完成了b目录下的所有文件的复制操作,准备退出b时,这时Windows说:
嘿嘿,我们定义的是可是“最后一次修改时间”啊,于是他把你之前设置的16:
18改成了你当前系统的时间20:
30。
于是之前的设置就被覆盖了。
在Linux下实现:
1、实验截图如下:
如图所示,在Linux平台下实现了文件的复制,成功的复制了普通文件和连接文件,连接文件包括硬连接文件和软连接文件(即符号连接文件。
2、实验中遇到的问题及分析
(1)区分硬连接和符号连接:
看了书本,感觉书本上讲的太抽象了,于是又上网查阅了很多资料。
我的理解如下:
硬连接hardlink:
实际使用文件时一般是通过文件名来引用的。
1个inode号码肯定和一片完全属于一个文件的数据区一一对应。
一个文件系统中两个或更多个不同的文件名实际上是可以对应于同一个文件的。
inode号码是记录在文件名对应的目录项中的,实际上可以使两个或多个文件的目录项具有相同的inode值,实际上就使它们对应着同一个文件。
有几个目录项具有相同的inode号,就说这个文件有几个硬连接,对于普通文件,ls-l命令的连接计数count域的数值就是本文件拥有的硬连接数。
硬连接可以通过ln命令建立,例如:
$lnl1l2$ls-ll*-rwxr-xr-x2userwheel53212Dec412:
36l1-rwxr-xr-x2userwheel53212Dec412:
36l2上面的例子使用ln创建了一个连接,然后在ls的结果中可以看到第二列的数字为2,这表示这个文件有两个连接。
就建立了一个新的文件l2,这个文件的inode同样是53212。
建立硬连接实际上只是增加了一个目录项,但并没有复制文件数据区,原文件的数据区由两个文件共享。
这一方面能够节约大量磁盘空间,同时可以保证两个文件能同步更新。
但是硬连接文件有两个限制:
a、不允许给目录创建硬连接b、只有在同一文件系统中的文件之间才能创建连接硬连接文件实际上并不是一种新的文件类型,两个文件互为对方的硬连接。
它们应该都是普通文件,更改了一个文件的权限位mode,另一个也会发生同样的变化。
(因为这些信息都保存在FCB即文件控制块中,FCB有放在索引结点(inode)中)。
软连接:
软连接又叫符号连接,这个文件包含了另一个文件的路径名。
可以是任意文件或目录,可以连接不同文件系统的文件。
和Windows下的快捷方式差不多。
例:
tanubuntu:
Documents$lns/home/tan/Documents/a/filefile-slink上面的例子在当前工作目录Documents下创建了目录文件file的一个符号连接文件,它的名字叫做file-slink,则可以在Documents文件夹下通过符号连接文件file-slink访问文件夹file下的各个文件。
符号连接本身也是文件,而不像上面的“硬连接”实际上是增加一个目录项,项中存在指向索引结点的指针。
所以符号连接有直接的索引结点,要耗费一定的磁盘空间,该符号连接文件中包含被连接文件的路径名。
所以只有文件才拥有指向其索引结点的指针,而共享该文件的其他用户,则通过符号连接“只拥有该文件的路径名”。
(2)在复制符号连接文件时花了不少时间,之前由于没有使用readlink和symlinkAPI,复制过去的东西根本就不是符号连接文件。
readlink不跟随符号链接,也就是说他打开的就是符号链接文件本身,而不继续找到所连接的文件。
复制的时候需要把符号连接文件的内容(也即所连接文件的路径名)读出来,再使用symlink创建新符号连接文件。
(3)虽然Linux修改文件时间不像Windows那样“不智能”,但是utime系统调用也把我折腾个半死。
其实大部分的修改文件时间操作都可以使用utime这一系统调用来实现,然而对于符号链接文件来说,则需要使用lutimes才能完成。
之前用utime来做,符号连接文件的文件时间老是为系统时间。
后来在Linux官方论坛上找到了lutimes这一API才把问题解决。
五、实验收获与体会本次实验给我的感触很大,主要有两点:
第一点,就拿lutimes这个LinuxAPI来说吧,他完成的使命就是修改符号连接文件的时间属性,但是我在XX上不管描述这一“使命”都找不到这个API,然而改用Bing英文搜索“Linuxsymbollink”,立马就出结果了。
第一次真心体会到了英文搜索比中文好的多。
第二点,Linux和Windows很多机制的设计的都不同。
比如说上述的Windows修改文件时间属性机制,然而Linux就没有这个。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 复制 文件 实验 报告