PIGWORLD

学无止境

1.4 文件与目录

1.4 文件与目录

文件系统

UNIX文件系统是按层次安排目录和文件的。起始目录被称为根(root),它的名字是一个字符 /

目录是一个包含目录项的文件。在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息。文件属性是:文件类型,文件长度,文件所有者,文件的许可权(例如,其他用户能否能访问该文件),文件最后的修改时间等。startfstat函数返回一个包含所有文件属性的信息结构。第4章将详细说明文件的各种属性。

目录项事实上存储在磁盘上,对此区别于目录项的逻辑看法。多数UNIX文件系统的实现并不在目录项中存储该目录项自己的属性,因为当文件有很多硬连接的时候,很难做到同步保存该文件的属性。当我们在第四章讨论硬连接后,对此将有清晰的认识。

文件名

目录中的各个名字被称为文件名。唯一两个不能出现在文件名中的字符是反斜杠(/)和空字符(null)。反斜杠用来把文件名从路径名中区别出来,空字符用来结束一个路径名。因此,把文件名中可用的字符限制在一般打印字符的子集中是一个好习惯。(我们限制可用字符还因为,如果我们在文件名中使用了shell的特殊字符,我们就必须使用shell的引号机制来引用文件名,这将导致问题复杂化。)

被反斜杆区分开,并且可选的以反斜杆开头一个或多个文件名的序列,构成了路径名。以反斜杆起头的路径名称为绝对路径;否则,称为相对路径。相对路径涉及到的文件相对于当前目录。文件系统的根(/)的名字是绝对路径的特例,它没有文件名。

例子

列出一个目录中所有文件的名字并不困难。图1.3展示了ls1)命令实现的本质。

ls1)符号是UNIX系统手册的一般表示方法,用来引用特定的项。它引用第一小节中的ls项。小节号通常用数字18表示,同时每一小节中的所有项都是按字母顺序排列的。本书中,我们假定你有一份你的UNIX系统手册的拷贝。

历史上,UNIX系统把所有8个小节集中在UNIX程序员手册中。随着页数的增加,趋势变为把各节安排在不同的手册中:例如一份为用户准备的,一份为程序员准备的,一份为系统管理员准备的。

一些UNIX系统使用大写字母在已有的小节中进一步细分手册。举例来说,所有AT&T中的标准输出/输入(I/O)函数在3S小节中,比如fopen3S)。其它系统用字母来代替数字表示小节号,例如用C表示命令。

今天,许多手册用电子形式进行发行。如果你的手册是联机手册,查看手册中ls命令的方式或许是这样的:

man  1  ls

或者

man  s1  ls

1.3是一个程序,其打印出目录中各个文件的名字。如果源码文件的名字是myls.c,我们按照以下方式把它编译成默认的可执行文件a.out

cc  myls.c

cc1)是早期的C编译器。在支持GNU C编译器的系统上,gcc1)是C编译器。这里,cc通常与gcc相连接(译者注:原句是Herecc is often linked to gcc。没翻译好,期待哪位大虾指教)。

一些输出例子如下:

$ ./a.out /dev

.

..

console

tty

mem

kmem

null

mouse

stdin

stdout

stderr

zero

省略其它未显示的行

cdrom

$ ./a.out /var/spool/cron

can’t open /var/spool/cron: Permission denied

$ ./a.out .dev/tty

can’t open /dev/tty: Not a directory

像上面那样,我们会以如下的方式展示运行的命令和该命令的输出:输入的字符以红色加粗字体显示,而程序的输出以红色字体显示。如果对于输出需要加注释,我们会以红色斜体字体显示注释。输入行前面的美元符号是shell打印出来的提示符。我们始终使用美元符号作为shell提示符。

注意文件名并没有按照字母顺序输出。而ls命令会在打印名字之前现对名字排序。

在这个20行的程序中,许多细节应当被考虑:

l         首先,我们包含了一个我们自己编写的头文件:apue.h。几乎本书中所有的程序都包含这个头文件。该头文件包含了一些标准系统头文件,并且定义了本书例子中使用的数值常量和函数原型。该头文件的清单在附录B中。

l         main函数的声明使用了ISO C标准的风格。(下章中我们会谈到更多ISO C标准。)

l         我们从命令行得到参数argv[1]作为对象目录的名字。在第七章,我们将看到main函数是怎样被调用的,同时看到命令行参数和环境变量是如何传递给程序的。

l         由于不同UNIX系统的目录项格式不尽相同,我们使用opendir函数,readdir函数和closedir函数来操作目录。

l         opendir函数返回DIR结构的指针,并传递该指针给readdir函数。不必关心DIR结构的细节。接着在循环中调用readdir函数,用来读取每个目录项。readdir函数返回一个dirent结构的指针,否则,在无目录项可读时返回null指针。我们只需要检查dirent结构中每个目录项的名字(d_name)。使用这个名字,我们就可以调用stat函数(4.2节介绍)来确定文件的所有属性。

l         我们调用两个我们自己编写的函数来处理错误:err_syserr_quit。从图1.3的输出中我们可以看到,err_sys函数打印出了丰富的信息来描述遇到的错误(“Permission denied”和“Not a directory”)。附录B中列出了这两个错误处理函数。在1.7节中我们将更详细的谈到错误处理。

l         当程序完成时,以参数0调用exit函数。exit函数结束一个程序。通常,参数0意味者正常结束,而1255之间的参数意味着发生了错误。8.5节中,我们将会学习一个程序(比如shell或者我们自己写的程序)如何获得另一个正在执行中的程序的exit状态。

http://pigworld.blogbus.com/files/1136135551.jpg

1.3 列举出一个目录中的所有文件

工作目录

每个进程都有一个工作目录,有时又称为当前工作目录。所有的相对路径都从该目录开始。一个进程能够用chdir函数改变它的工作目录。

例如,相对路径doc/memo/joe指出memo目录中的文件或目录joememo目录又在doc目录中,而doc一定是工作目录下的一个目录。查看这个相对路径,我们知道docmemo一定是目录,但是我们不能确定joe是一个文件还是一个目录。路径/usr/lib/lint是一个绝对路径,它指出了lib目录中的文件或目录lintlib目录在usr目录中,而usr目录又在根(root)目录中。

起始(Home)目录

当我们登录时,工作目录被设定为我们的起始目录。我们的起始目录是从密码文件(1.3节介绍)中我们的登录项得到的。

posted on 2006-01-03 22:00 PIGWORLD 阅读(982) 评论(0)  编辑 收藏 引用 所属分类: 《UNIX环境高级编程(第二版)》翻译


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理