三.
文件和目录
重点:
l
ls –l file
将文件属性的几个重点部分
文件类型
;
文件权限
;
链接个数
;
所有者用户
ID/name
,组
ID/name;
文件大小
;
最近修改时间
l
目录以及其
entry
的访问方法
sudo chown root filename
更改文件所有者
sudo chgrp root filename
更改文件所在用户组
3.1
取得文件的属性信息
我们后面有个练习要模拟
ls
,所以我们的介绍也是围绕这个展开的。
3.1.1
取文件属性信息的函数
stat()/fstat()/lstat()
l
三个函数可以获取文件属性信息。强调文件包括很多种,普通文件,目录等等
l
三个文件的差别:特别是stat
和lstat
。stat
函数返回一个与此命名文件有关的信息结构;lstat
函数类似于stat
,但是当命名的文件是一个符号连接时,lstat
返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息。
l
fstat
函数获得已在描述符filedes
上打开的文件的有关信息。
l
讲
stat
和
lstat
之间的差别时讲解一下硬链接,软链接,以及它们之间的差别。
3.1.2 struct stat
定义:
重点讲解一下我们关心的字段。为后面铺垫。
Notes: Struct stat ->
参考man 2 stat
举例:
<<<<<<<<<<
利用st_size
获取文件大小同时对比一下
lstat
和
stat
对软链取到的文件大小的区别:
samples\3-dir\3.1\ getfilesize_stat.c
samples\3-dir\3.1\ getfilesize_lstat.c
用
ln
命令创建软链接,
ln <-s> sourcefile linkfile
,比较
lstat
和
stat
对软链取到的文件大小的差别
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
3.1.3
文件的类型:
注:这个概念一期已经有过介绍,可以通过让学生回顾并伴随一些快速的演示
“
-”普通文件;“
d”目录;“
l”符号链接;“
c”
字符设备;“
b”
块设备;
“p” 有名管道;“s” Socket文件。
举例:
<<<<<<<演示用
stat函数和宏来取得文件的类型信息,
samples\3-dir\3.1\ls_filetype.c
>>>>>>>>
3.1.4
文件存取许可权限
Linux的文件权限是
Linux能有如此安全性能的最大的保障之一,有朋友可能会知道,很多攻击
windows的方法都是通过漏洞获取到创建用户的权限从而达到控制计算机的目的。
UNIX
通过将用户分类来控制不同用户对某个资源的访问,同时将访问抽象为读写和执行三大类。
3.1.4.1
用户的分类
用户按照“
文件的所有者”
、“
所有者所在用户组”
和“
组外其他用户”分成三类
。
l
文件的所有者
:Linux
作为一种网络操作系统,允许多个用户使用。为了保护用户的个人文件不被其他用户侵犯,Linux
提供了文件权限的机制。这种机制使得一个文件或目录归一个特定的用户所有,这个用户有权对他所拥有的文件或目录进行存取或其他操作,也可以设置其他用户对这些文件或目录的操作权限。
l
文件的所有者所在用户组
:每个用户在建立用户目录时都被放到至少一个用户组中(当然,系统管理员可以将用户编进多个用户组中)。用户组通常是根据使用计算机的用户的种类来划分的。例如,普通用户通常属于usrs
组。另外,还有几个系统定义的组(如bin
和admin
),系统使用这些组来控制多个人对同一类资源的访问。
l
组外其他用户
。
3.1.4.2
访问操作的分类:
l
普通文件的权限有三部分:读、写和执行。分别用“r”
、“w”
、“x”
来表示。
l
目录也有这三种表示方式,r
表示列出本目录内容、w
表示在本目录中new
,rename
或delete
文件和修改目录的属性、x
表示是否可以进入该目录。特别地如果我们在命令中指定了一个路径,则如果我们要通过这个路径访问路径末端的文件,则需要对该路径的每一级目录都拥有x
。
l
讲清楚了前面两点,再过一下课件的P81
左边的7
条。
举例:
<<<<演示用
stat函数和宏来取得文件的访问权限信息,
samples\3-dir\3.1\ls_fileperm.c
>>>>>>>>>
3.1.5
文件所有者名和所在组名
l
在介绍uid
和gid
的基础上介绍OS
在我们访问文件中执行的检测逻辑
举例:
<<<<<演示用
stat函数和宏来取得文件的所有者和所有者组的信息
介绍getpwuid
和getgrgid
,以及struct passwd; struct group
,
samples\3-dir\3.1\ls_fileowner.c
Man 3 getpwuid ,Man 3 getgrgid,
文件所有者的信息存放在
struct passwd
这个结构体里
文件所属用户组信息存放在
struct group
里。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
举例
+
实验
<<<<<<
实现一个简单的
ls –l file
的功能。这个例子我先演示一下,然后让学生自己看看并实际操练一下,作为对上面知识的总结。
D:\work\courses\notes\2.1-IO\labs\
3-ls1\myls.c
,不要求其他的参数,
演示重点:
1
)除了已经讲过的部分,还需要讲解一下
st_nlink
;
st_mtime
(包括其他时间
man 2 stat
);软链接
1)
演示绝对路径和相对路径
2)
演示读不同的文件类型,至少包括
regular
,
directory
,
link
。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
3.2
目录读取函数
重点讲解
opendir/closedir
和
readdir
函数 | 说明 |
#include <dirent.h> DIR *opendir(const char *pathname) | Returns: pointer if OK, NULL on error 如果name是一个合法的目录名,opendir函数返回这个目录的句柄。返回的这个句柄主要给读目录函数readdir用的。如果是一个非法的目录名,此函数返回NULL; DIR结构是一个内部结构,类似于FILE结构。 可以将DIR比喻为父目录,direntry是父目录下的文件/子目录。Opendir运行后会产生一个内部的链表,DIR为链表头,通过反复调用readdir来遍历这个链表。 |
struct dirent *readdir(DIR *dp); | Returns: pointer if OK, NULL at end of directory or error readdir函数需要opendir得到的句柄,每调用一次,返回当前目录中一个文件的信息。文件信息的由struct dirent结构体进行描述。 有关dirent的描述可以man readdir 重点: d_type(有问题,不是所有操作系统都支持所以不建议使用), d_name |
#include <sys/types.h> #include <dirent.h> int closedir(DIR *dirp); | 关闭打开的目录对象 |
#include <unistd.h> int chdir(const char *pathname); Both return: 0 if OK, 1 on error | 这个函数可选讲解 每个进程都有一个当前工作目录,此目录是搜索所有相对路径名的起点,当用户登录到UNIX系统时,其当前工作目录通常是口令文件/etc/passwd中该用户登录项的第6个字段-用户的起始目录。 当前工作目录是进程的一个属性。所以只影响调用chdir的进程本身,不会影响其他进程。 |
举例:
<<<<< Opendir
和
readdir
的组合使用,
samples\3-dir\3.2
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
实验:
<<<<<<<<<
D:\work\courses\notes\2.1-IO\labs\
3-ls2\myls.c
该实验在
3-ls1
的基础上更进一步,要求如果输入一个目录,要列出该目录下的所有条目
dir entry
,以及每个条目的详细内容信息。
先讲一下注意点:
ls1
的代码可以抽象为对每个
dirent
的操作,但需要我们拼装路径。
看学生反应,可以建议学生分两步完成,第一步实现路径拼接;第二步,抽象函数。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>