perl教程010

perl教程010 - 下载 第 10 学时

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: 下载 第 10 学时 文件与目录 操作系统中的文件为数据提供了一个非常方便的存储方式。操作系统为数据提供了一个 名字(即文件名)和一个组织结构,这样你就可以在以后找到你要的数据。这个组织结构称 为文件系统。然后你的文件系统再将文件分成各个组,称为目录,有时也称为文件夹。这些 目录能够存放文件或其他目录。 在目录中嵌套目录的方法给计算机中的文件系统提供了一个树状结构。每个文件都是一 个目录的组成部分,每个目录又是父目录的组成部分。除为你的文件提供一个组织结构外, 操作系统还存放了关于文件的各种数据,比如上次读取文件是在什么时候,上次修改文件是 在什么时候,谁创建了文件,当前文件有多大等等。所有的现代计算机操作系统几乎都采用 这种组织结构。 在 M a c i n t o s h 系统中,仍然采用这种结构,不过它的高层目录称为卷,子目录称为文件 夹。 P e r l允许你访问这个组织结构,修改它的组织方法,并可查看关于文件的各种信息。 P e r l 用于这些操作的函数全部源自 u n i x操作系统,但是在 P e r l 运行的任何操作系统下,这些函数都 能够很好地运行。 P e r l的文件系统的操作函数是可以移植的,也就是说,如果你使用 P e r l 的函 数对你的文件进行操作并查询你的文件,那么在 Perl支持的任何操作系统下,运行你的代码都 是没有问题的,只要目录结构相类似。 在本学时中,你将要学习: • 如何获得目录列表。 • 如何创建和删除文件。 • 如何创建和删除目录。 • 如何获取关于文件的信息。 10.1 获得目录列表 从系统中获取目录信息的第一步是创建一个目录句柄。目录句柄与文件句柄相类似,不 同之处是:不是通过读取文件句柄来获得文件的内容,而是使用目录句柄来读取目录的内容。 若要打开目录句柄,可以使用 opendir函数: 在这个语句中, dirhandle是要打开的目录句柄, directory是要读取的目录的名字。要是目 录句柄不能打开,你就无权读取该目录的内容,或者该目录根本不存在。 o p e n d i r函数将返回 假。目录句柄的结构应该与文件句柄相类似,它使用第 2 学时介绍的变量名的创建规则,目录 句柄应该全部使用大写字母,以避免与 Perl 的关键字发生冲突。下面是目录句柄的一个例子: 本学时中介绍的所有例子都使用 U N I X样式中的正斜杠,因为与反斜杠相比,它不易产生 混乱,并且它可以同时用于 UNIX和Windows操作系统。 114 使用第二部分 高 级 特 性 下载 目录句柄打开后,可以使用 readdir函数来读取它的内容: 在标量上下文中, r e a d d i r 函数返回目录中的下一项,如果目录中没有剩下任何项目,则 返回 u n d e f 。在列表上下文中, r e a d d i r返回所有的(剩余的)目录项。 r e a d d i r 返回的名字包括 文件、目录的名字,而对于 UNIX来说,则返回特殊文件的名字。它们返回时没有特定的次序。 readdir返回目录项 .和..。readdir返回的目录项不包含作为目录名的组成部分的路径名。 当完成目录句柄的操作后,应该使用 closedir函数将它关闭: 下面这个例子说明如何读取一个目录: 在上面这个代码段中,整个目录被读入 @ F I L E S中。不过,在大多数时候,你对 .和. . 文件 是不感兴趣的。若要读取文件句柄并清除这些文件,可以输入下面的代码: 正则表达式( / ^ \ . \ . ? $ / )用于匹配也位于行尾的一个前导原义圆点(或两个圆点) ,而 g r e p 则用于清除它们。若要获得带有特定扩展名的全部文件,可以使用下面的代码: readdir返回的文件名并不包含 opendir使用的路径名。因此,下面的例子可无法运行: 除非你在运行代码时恰好在 / t m p 目录中工作,否则 o p e n ( F I L E H ,$ f i l e )语句的运行将会失 败。例如,如果 / t m p 中存在文件 m y f i l e . t x t,那么 r e a d d i r便返回 m y f i l e . t x t。当你打开 m y f i l e . t x t 时,实际上必须使用全路径名来打开 /tmp/myfile.txt。正确的代码如下所示: Globbing 读取目录中的文件名时使用的另一种方法称为 globbing。 如果你熟悉 DOS中的命令提示符, 那么一定知道命令 dir*.txt 可用于输出以 .txt结尾的所有文件的目录列表。在 UNIX中, globbing 是由 shell来完成的,但是 ls*.txt几乎能产生相同的结果,即列出以 .txt结尾的所有文件。 Perl有一个操作符,能够进行这项操作,它称为 glob。Glob的句法是: giob pattern 这里的 pattern是你要匹配的文件名模式。 pattern 可以包含目录名和文件名的各个部分。此 外, pattern可以包含表 10-1列出的任何一个特殊字符。在列表上下文中, glob返回与模式匹配 的所有文件(和目录) 。在标量上下文中,每查询一次 glob,便返回一个文件。 115 第10学时 文件与目录使用 下载 glob的模式与正则表达式的模式不同。 表10-1 globbing 的模式 字 符 匹配的模式 ? * [chars] 单个字符 任何数目的字符 用于匹配任何一个 chars; MacPerl 不支持这个特性 既可以匹配字符串 a , 也可以匹配字符串 b , {a , b,… } 举 例 f? d 用于匹配 fud 、 fid 和 fdd 等。 f*d 用于匹配 fd、 fdd 、 food 和 filled等 f[ou]d 用于匹配 fod 和 fud ,但不能匹配 fad f*{txt , doc} 用于匹配以 f 开头并且以 .txt 或 .doc结 尾的文件 MacPerl 不支持这个特性 对于 U N I X 爱好者来说, P e r l 的 g l o b 操作符使用 C语言的 s h e l l 样式的文件 g l o b b i n g ,而不是 B o u r n e(或 K o r n ) s h e l l的文件 g l o b b i n g 。它适用于安装了 P e r l 的任何 U N I X 系统,而不管你个人使用的是何种 s h e l l 。 Bourne shell g l o b b i n g和 Korn shell globbing 不同于 C 语言的 shell globbing 。它们在某些 方面很相似,比如 * 与 ? 的运行特性相同,但是在其他方面差别很大,请注 意。 下面请看几个 globbing的例子: 下面是使用 glob与opendir/readdir/closedir 之间的某些差别: • glob只能返回有限数量的文件。对于较大的目录, glob可能会报告“太多的文件” ,但是 却不能返回任何文件。这是因为 g l o b 当前是使用外部程序即 s h e l l来实现的,它只能返回 有限数量的文件。 opendir/readdir/closedir函数则不存在这个问题。 • g l o b 返回模式中使用的路径名,而 o p e n d i r / r e a d d i r / c l o s e d i r 函数则不能。例如, g l o b ( / u s r / i n c l u d e / * . h ’ / u s r / i n c l 作为任何匹配项的组成部分,而 r e a d d i r则不能返 ‘ )返回 ‘ ude’ 回它。 • g l o b 的运行速度通常比 o p e n d i r / r e a d d i r / c l o s e d i r慢。同样,它之所以运行速度比较慢,是 因为 P e r l 必须启动一个外部程序来为它进行 g l o b b i n g ,而该程序将在对文件名排序后再 返回这些文件名。 那么你究竟应该使用哪一个函数呢?这完全取决于你。不过,使用 opendir/readdir/ c l o s e d i r函数往往是个复杂得多的解决方案,在本书中的大多数程序例子中,我们都使用这个 函数。 116 使用第二部分 高 级 特 性 下载 为了完整起见, P e r l 提供了另一种方法,用于编写模式 g l o b 。只需将模式放入尖括号运算 符( <> )中,就可以使尖括号运算符像 glob函数那样来运行: 用于 globbing 的尖括号运算符的句法比较老,并且可能引起混乱。在本书中,为了清楚起 见,将继续使用 glob函数。 10.2 练习:UNIX的grep 当你进一步阅读本书的内容时,一些练习将为你展示更多的非常有用的工具。下面这个 练习展示了一个 U N I X的 g r e p 实用程序的简化版本。 U N I X的 g r e p (不要与 P e r l 的 g r e p 相混淆) 用于搜索文件中的模式。这个练习展示了一个实用程序,它提示你输入一个目录名和一个模 式。目录中的每个文件均被搜索,以便寻找该模式,与该模式相匹配的文件行将被输出。 使用文本编辑器,键入程序清单 1 0 - 1的程序,并将它保存为 m y g r e p 。务必按第 1 学时中介 绍的方法使该程序成为可执行程序。另外,一定不要将该文件改名为 U N I X系统上的 g r e p,它 可能被混淆为实际的 grep实用程序。 完成上述操作后,键入下面的命令行,设法运行该程序: perl mygrep 程序清单 10-1 mygrep的完整清单 第1行:这一行包含到达解释程序的路径(可以修改它,使之适合系统的需要)和开关 -w。 请始终使警告特性处于激活状态。 第3行: use strict 命令意味着所有变量都必须用 my来声明,并且裸单词必须加上引号。 第5 ~ 8 行: $ d i r(要搜索的目录)和 $ p a t (要搜索的模式)是从 S T D I N中检索而来的。每 117 第10学时 文件与目录使用 下载 行结尾处的换行符均被删除。 第10行: $file被声明为符合 use strict 的专用变量。 $file用在本程序的后面。 第12行:目录 $dir被打开,如果这项操作没有成功,则输出一条出错消息。 第13行:从目录中检索各个条目,每次检索 1条,然后存入 $file。 第 1 4 行:确实是目录本身( - d )的任何目录条目均被拒绝。请注意,被核实的路径名是 $ d i r / $ f i l e。核实该路径是必要的,因为当前目录中不一定存在 $ f i l e ,它存在于 $ d i r中。因此该 文件的全路径名是 $dir/$file。 第15~18行:文件被打开,再次使用全路径名 $dir/$file,如果文件没有打开,则被拒绝。 第19~23行:文件被搜索,逐行进行搜索,找出包含 $pat的这一行。匹配的行将被输出。 程序清单 10-2显示了 mygrep程序的输出举例。 程序清单 10-2 mygrep 的输出 10.3 目录 到现在为此,本学时中一直在介绍目录结构的问题。为了打开文件,有时需要它的全路 径名, r e a d d i r函数能够读取目录。但是,如果要浏览目录,添加和删除目录,或者清除目录, 则需要更多的 Perl 功能。 10.3.1 浏览目录 当你运行软件时,操作系统将对你所在的目录保持跟踪。当你登录到一台 U N I X计算机中 并且运行一个软件包时,通常要进入你的主目录。如果你键入操作系统的命令 pwd,shell便向 你显示你是在什么目录中。如果你使用 D O S或Wi n d o w s操作系统,并且打开一个命令提示符, 该提示符就能反映出你当时是在什么目录中,比如 C : \ W I N D O W S。另外,你也可以在 D O S提 示符后面键入操作系统命令 c d ,这样, D O S就会告诉你是在什么目录中。你当前使用的目录 称为当前目录,即你的当前工作目录。 如果你使用程序编辑器或者集成式编辑器 / 调试器,并且直接从那里运行 你的 P e r l 程序,那么“当前目录”可能不是你想像的那个目录。它可能是 P e r l 程序所在的目录,编辑器所在的目录或者是任意其他的目录,这取决于你使 用何种编辑器。如果要确定当前目录究竟是什么,请在你的 P e r l 程序中使用 cwd函数。 如果没有全路径名,也可以打开文件,比如: o p e n(F H, f i l e ” | | d i e 可以在你的当前目 “ ) 录中打开。若要改变当前目录,可以使用下面这个 chdir函数: chdir newdir; chdir函数将当前工作目录改为 newdir。如果 newdir目录不存在,或者你不拥有对 newdir的 访问权,那么 c h d i r返回假。 c h d i r 对目录的改变是暂时的,一 P e r l 程序运行结束,就返回运 118 使用第二部分 高 级 特 性 下载 行Perl程序之前所在的目录。 如果运行的 c h d i r 函数不包含一个目录作为其参数,那么 c h d i r 就会将你的目录改为你的主 目录。在 U N I X 系统上,主目录通常是你登录时进入的这个目录。在 Windows 95 、 Wi n d o w s N T或 D O S计算机上, c h d i r会使你进入 H O M E环境变量中指明的这个目录。如果 H O M E 没有设 置, chdir 将根本不改变当前目录。 Perl并不配有任何内置函数来确定当前目录是个什么目录,因为某些操作系统编写时所采 用的方法,使得函数很难做到这一点。若要确定当前目录,必须同时使用两个语句。在程序 的某个位置,最好是在靠近程序开始的地方,必须使用语句 use Cwd,然后,当你想要检查当 前目录时,使用 cwd函数: 只能执行 use Cwd 语句一次,此后,可以根据需要多次使用 cwd函数。 语句 use Cwd 实际上让 P e r l 加载一个称为 Cw d 的模块,使 P e r l语言增加一 些新的函数,如 C w d 。如果上面介绍的这个代码段返回一条出错消息,说 Can’t locate cwd .pm in @INC (在 @INC中找不到 Cwd.pm ) ,或者你不完全理 解各个模块,那么现在不必为此而担心,第 1 4学时将要详细介绍模块方面的 知识。 10.3.2 创建和删除目录 若要创建一个新目录,可以使用 Perl的mkdir 函数, mkdir函数的句法如下: 如果目录 n e w d i r能够创建,那么 m k d i r 函数返回真。否则,它返回假,并且将$!设置为 mkdir 运行失败的原因。只有在 Perl的UNIX 实现代码中, permissions才真的十分重要,不过在 所有版本中都必须设置 p e r m i s s i o n s 。对于下面这个例子,使用的值是 0 7 5 5 。这个值将在本学 时后面部分中的“ U N I X系统”这一节中介绍。对于 D O S 和Wi n d o w s用户来说,只使用 0 7 5 5 这 个值就足够了,可以省略冗长的说明。 若要删除目录,可以使用 rmdir函数。 rmdir函数的句法如下: 如果目录 p a t h n a m e 可以删除, r m d i r函数返回真。如果 P a t h n a m e 无法删除, r m d i r 返回假, 并将$!设置为 rmdir运行失败的原因,如下所示: r m d i r函数只删除完全是空的目录。这意味着在目录被删除之前,首先必须删除目录中的 119 第10学时 文件与目录使用 下载 所有文件和子目录。 10.3.3 删除文件 若要从目录中删除文件,可以使用 unlink函数: u n l i n k 函数能删除 l i s t _ o f _ f i l e s 中的所有文件,并返回已经删除的文件数量。如果 list_of_files被省略,$ _中指定的文件将被删除。请看下例: 若要检查文件列表是否已被删除,必须对想要删除的文件数量与已删除的文件数量进行 比较,如下面这个例子所示: 在上面这个代码段中,被 u n l i n k 删除的文件数量将存放在 $ e r a s e d 中。 u n l i n k 运行后, $ e r a s e d 的值将与 @ f i l e s中的元素的数量进行比较,它们应该相同。如果不同,便输出一条出 错消息,显示“剩余的”文件。 用 u n l i n k 函数删除的文件将被绝对地清除掉,它们将无法恢复,并且不 是被转入“回收站” ,因此使用 unlink函数时应该格外小心。 10.3.4 给文件改名 在Perl中给文件或目录改名是很简单的,可以使用 rename函数,如下所示: r e n a m e函数取出名字为 o l d n a m e的文件,将它的名字改为 n e w n a m e。如果改名成功,该函 数返回真。如果 o l d n a m e 和 n e w n a m e 是目录,那么这些目录将被改名。如果改名不成功, rename 返回假,并将$!设置为不成功的原因,如下所示: 如果你设定了路径名,而不只是设定文件名,那么 r e n a m e函还会将文件从一个目录移到 另一个目录,如下例所: 如果文件 newname已经存在,该文件将被撤销。 如果文件是在不同的文件系统上,那么 r e n a m e函将不会把文件从一个目 录移到另一个目录中。 120 使用第二部分 高 级 特 性 下载 10.4 UNIX系统 下面介绍 P e r l 用户在 U N I X 操作系统下工作的情况。如果你不是在 U N I X 系统上使用 P e r l, 那么可以跳过本节,你不会遗漏任何重要的内容。如果你对 U N I X 非常有兴趣,可以阅读这一 节的内容。 作为 U N I X用户来说,应该知道 P e r l与 U N I X系统之间有着很深的渊源关系,有些 P e r l函数 直接来自 U N I X 命令和操作系统函数。这些函数中,大部分是你不使用的。有些函数,如 u n l i n k ,虽然源于 U N I X,但其含义却与 U N I X 毫无关系。每个操作系统都可以用来删除文件, P e r l 能够确保 u n l i n k 会对操作系统执行正确的操作。 P e r l作出了很大的努力,以确保有关的特 性(如文件 I / O )能够在操作系统之间移植,并且它在可能的情况下将所有的兼容性问题隐藏 起来,使你不必为此而担心。 Perl语言中嵌入了许多 UNIX函数和命令,而 Perl语言已经移植到许多非 UNIX操作系统中, 这满足了 U N I X 开发人员和管理员的要求,使他们能够将 U N I X工具包中的一些工具带到任何 地方去使用。 正如下一节的标题所示,这个描述不能被视为 UNIX文件系统访问许可权 以及如何操作文件的完整说明。若要了解它的完整说明,请参见你的操作系统 文档,或者参阅关于 UNIX的其他著作,如《 UNIX 24 学时教程》 。 文件访问许可权的简要介绍 在第1学时中,我们讲到,为了使 Perl程序能够像一个标准命令那样来运行,我们提供了一 个命令chmod 755 scriptname ,但是没有具体介绍它的含义。 755是赋予文件scriptname的访问许 可权的一种描述。 UNIX中的chmod命令用于设置文件的访问许可权。 775 这行数字分别代表赋予文件所有者、文件所属小组以及其他的 非文件所有者和非文件所属小组的访问许可权。在上面这个例子中, 文件所有者拥有的访问许可权是 7 ,文件所属小组和其他人的访问许 所有者 组 其他人 可权是 5。表 10-2列出了每种访问许可权的值。 表10-2 访问许可权值 7 6 5 4 3 2 1 文件访问许可权 权 限 所有者/组/其他人可以读、写和执行该文件 所有者/组/其他人可以读、写该文件 所有者/组/其他人可以读和执行该文件 所有者/组/其他人可以读该文件 所有者/组/其他人可以写和执行该文件 所有者/组/其他人可以写该文件 所有者/组/其他人可以执行该文件 若要在 Perl中设置文件的访问许可权,可以使用 UNIX的内置函数 chmod: chmod函能够改变 list_of_files的所有文件的访问许可权,并且返回已经改变访问许可权的 文件数量。 m o d e的前面必须有一个数字 0(如果它是一个八进制直接量数字的话) ,然后是你 121 第10学时 文件与目录使用 下载 想指明其访问许可权的数字。下面是 chmod命令的一些例子: 在本学时前面部分的内容中,我们介绍了 m k d i r 函数。 m k d i r 的第一个参数是文件访问许 可权,它与 chmod使用的许可权是相同的: U N I X 文件的访问许可权常常称为它的“方式” 。因此 c h m o d 是“ c h a n g e mode(改变方式) ”的缩写。 10.5 你应该了解的关于文件的所有信息 如果你想要详细而全面地了解关于一个文件的信息,可以使用 P e r l的s t a t 函数。 s t a t 函数源 于UNIX系统,它的返回值在 UNIX系统中与非 UNIX系统中略有不同。 Stat的句法如下所示: s t a t函数即可以用来检索已经打开的文件句柄的信息,也可以检索关于某个特定文件的信 息。在任何操系统下, s t a t 均可返回一个包含 1 3个元素的列表,来描述文件的属性。列表中 的实际值随着运行的操作系统的不同而有所差异,因为有些操作系统包含的特性是其他操作 系统所没有的。表 10-3 显示了 stat返回值中的每个元素的含义。 表10-3 stat 函数的返回值 编 号 名 字 UNIX系统 0 dev 设备号 1 2 3 ino mode nlink 索引节号 文件的方式 链接号 4 5 6 7 8 9 10 11 12 uid gid rdev size atime mtime ctime blksz blocks 文件所有者的用户 ID ( UID) 文件所有者的组 ID ( GID ) 特殊文件信息 文件大小(以字节计) 上次访问的时间 上次修改的时间 Inode修改时间 磁盘块的大小 文件中的块的数量 Windows 系统 驱动器号( C:通常是 2 ,D : 通常是 3 ,等等) 总是 0 无 通常为 0 ; Windows NT ;文 件系统允许链接 总是 0 总是 0 驱动器号(重复) 文件大小(以字节计) 上次访问的时间 上次修改的时间 文件的创建时间 总是 0 总是 0 表1 0 - 3中的许多值你可能永远不会使用,但是为了完整起见,我们在表中将它们列出来。 对于含义比较含糊的值,尤其是 U N I X 中的返回值,你可以查看操作系统的参考手册,以了解 它的含义。 下面是将 stat用于文件的一个例子: 122 使用第二部分 高 级 特 性 下载 通常情况下,为了清楚起见, stat的返回值被拷贝到标量的一个赋值列表: 若要按“文件访问许可权的简要介绍”这一节中所说的 3字符形式输出文件的访问许可权, 可以使用下面这个代码,其中的 @stuff包含了访问许可权: 上面这个代码所包含的元素你可能不了解,这没有什么关系。其中有些元素尚未向你介 绍。在$ mode 中由 stat检索的元素包含了许多“额外的”信息。 &0777只是提取你感兴趣的这 部分信息。最后,% 0 是一个 p r i n t f 格式,用于输出采用 0 ~ 7格式的八进制数字, U N I X 希望用 这种格式对文件访问许可权进行格式化。 八进制是以 8 为基数的数字表示法。由于历史原因,它用于 U N I X 系统, 不过它也用于 P e r l 。如果你仍然对它不太理解,请不必担心。如果需要显 示文件的访问许可权,只要使用前面介绍的 p r i n t f函数即可。它并不是经常 出现。 表1 0 - 3 中列出的 3个时间戳,即访问时间、修改时间和更改(即创建)时间均以特定格式 来存储。时间戳以格林威治时间 1 9 7 0年 1 月1 日零点起的秒数来存储。若要以便于使用的格式 来输出时间,可以使用 localtime函数,如下所示: 该函数用于输出文件的修改时间,格式为 Sat Jul 3 23:35:11 EDT 1999 。访问时间是指上 次读取文件(或打开文件以便读取)的时间,修改时间是指上次将数据写入文件的时间。在 U N I X 系统下, “更改”时间是指更改关于文件的信息(文件的所有者、链接的数量、访问许 可权等)的时间,它并不是文件的创建时间,不过由于巧合,它常常就是文件的创建时间。 在Microsoft Windows下, ctime域实际上用于存放文件的创建时间。 有时你可能想从 s t a t 返回的列表中仅仅检索 1 个值。若是这样,可以用括号将整个 s t a t 函数 括起来,并使用下标将你想要的值标出来: 10.6 练习:对整个文件改名 这个练习为你的工具包提供了另一个小型工具。假定有一个目录名,一个要查找的模式 和要改变成的模式,使用这个实用程序,可以对目录名中的所有文件进行改名。例如,如果 一个目录中包含文件名 C h a p t e r _ 0 1 . r t f 、C h a p t e r _ 0 2 . r t f 、C h a p t e r _ 0 4 . r t f等,你就可以将所有文 件改名为 Hour_01.rtf、Hour_02.rtf、Hour_04.rtf等。当使用基于图形用户界面的文件浏览器时, 想要用命令提示符来执行这种操作常并不容易,而且显得很笨。 使用文本编辑器,键入程序清单 1 0 - 3 中的程序,并将它保存为 R e n a m e r 。务必按照第 1学 时介绍的方法使该程序成为可执行程序。 完成上述操作后,键入下面的命令行,设法运行该程序: 123 第10学时 文件与目录使用 下载 程序清单 10-3 Renamer 程序的完整清单 第13~15行: $dir指明的目录中的条目被读入 @files。 第1 7 ~ 1 9行:来自 @ f i l e s 的每个文件均被赋给$ _ ,并且该名字被保存在$ o l d n a m e 中。然 后,$ _中的原始文件名被改为 19行上的新名字。 第2 0 行:在对文件改名之前,这一行要确认目标文件名并不存在。否则,该程序可能将 文件改名为一个现有文件名,撤消其原始数据。 第2 1 ~ 2 5行。该文件被改名,如果改名失败,则输出一条警告消息。请注意,原始目录名 必须附加到文件名上,例如, $ / d i r / $ o l d n a m e ,因为 @ f i l e s不包含全路径名,所以必须使用全 路径名来进行改名。 程序清单 10-4显示了该程序的示例输出。 程序清单 10-4 Rename 程序的输出示例 10.7 课时小结 本学时我们介绍了如何使用 P e r l中的 m k d i r 、r m 和r e n a m e 函数来创建、删除目录条目并对 其改名。另外,还介绍了如何使用 s t a t来查询文件系统,以便了解关于文件的信息,不光是了 解文件的内容。在本学时中,两个练习提供了一些简单而实用的工具,使你的程序具备更高 的效能。 124 使用第二部分 高 级 特 性 下载 10.8 课外作业 10.8.1 专家答疑 问题: 我在运行下面这个程序时遇到了问题。虽然目录中有文件,但是无法读取,原因 何在? 解答: 问题出在第 2行上。 D I R H A N D L E是个目录句柄,不是文件句柄。你无法用尖括号 (<>)操作符来读取目录句柄。读取目录的正确方法是 @files=readdir DIRHANDLE。 问题: 为什么 glob(“*.*”)不能匹配目录中的所有文件? 解答: 因为“ * . * ”只能匹配文件名中有圆点的文件名。若要匹配目录中的所有文件,请 使用 glob(*.*)。glob 函数的模式可以在许多不同操作系统之间进行移植,因此它的运行特性与 DOS中的 *.*不同。 问题: 我修改了 m y g r e p 这个练习,以便使用 o p e n d i r 和更多的循环来搜索子目录,但是它 似乎存在某些错误。为什么? 解答: 总之,你不要这样做。向下搜索目录树是个老问题,它并不很容易,以前曾经多 次解决过这个问题,而你自己没有必要这样去做。 (从事全部这项工作称为“重新发明车轮” ) 。 如果你只是因为好玩而这样做,这很好,但是不要在这上面耗费太多的时间。请等到第 1 5学 时,你将会了解到如何使用 F i l e: F i n d 这个方法。它用起来更加简单,但是更加重要,它能 : 够进行程序调试。 问题: 如果我将 *.bat改为 *.tmp,程序清单 10-3中的程序就会出错,为什么? 解答: 该程序并不希望你键入 * . b a t作为要搜索的模式。在正则表达式中使用 * . b a t是无效 的, * 必须放在另外某个字符的后面。如果你输入了 \ * \ . b a t ,该程序完全可以接受这个输入, 不过它不会像你期望的那样运行,因为文件名中从来没有原义字符 *。 为了纠正这个错误,你可以为该程序提供它期望的输入(简单字符串) ,也可以将程序清 单的第 19行改为 s/\Q$oldpat/$newpat/ ,这样,正则表达式模式中的“特殊字符”将不起作用。 10.8.2 思考题 1) 若要输出文件 foofile的上次修改时间,应该使用: a. print glob(“foofile ”); b. print (stat( “foofile”))[9]; c. print scalar localtime (stat ( “foofile ”))[9]; 2) unlink 函数返回的是: a. 实际删除的文件数量。 b. 真或假,根据函数运行是否成的情况而定。 c. 试图删除的文件数量。 10.8.3 解答 1) 答案是 b 或c 。如果选择 b ,输出的时间为 1 9 7 0年以来的秒数,没有什么用处。如果 下载 125 第10学时 文件与目录使用 选择 c,则输出格式很好的时间。 2) 答案是 a。不过,选择 c,在某种情况下也是可以的。如果没有文件可以删除, unlink返 回0,表示假。 10.8.4 实习 • 设 法编写一个程序,列出目录中的所有文件、它的子目录中的所有文件等。这只作为一 个编程练习。 ...
View Full Document

This note was uploaded on 11/27/2011 for the course CS Perl taught by Professor Guo during the Spring '09 term at Xiamen University.

Ask a homework question - tutors are online