UNIX高级编程:第4章 文件和目录

请移步到:

http://note.youdao.com/noteshare?id=6d6b7090dfc2623d8d3ef7d961071cc3&sub=AB26FD611478406C986BDE7D5C51934B

4.2 函数stat,fstat,fstatat 和 lstat

int stat( const char *path, struct stat *buf);

int fstat( int fd, struct stat *buf);

int lstat( const char *path, struct stat *buf);

int fstatat( int dirfd, const char *pathname, struct stat *buf, int flags);

struct stat { dev_t st_dev; /* ID of device containing file -文件所在设备(硬盘,或者其他)的ID*/ ino_t st_ino; /* inode number -inode节点号*/ mode_t st_mode; /* protection -文件对应的模式,文件,目录等*/ nlink_t st_nlink; /* number of hard links -链向此文件的连接数(硬连接)*/ uid_t st_uid; /* user ID of owner -user id-文件所有者*/ gid_t st_gid; /* group ID of owner - group id-文件所有者的组号*/ dev_t st_rdev; /* device ID (if special file) -设备号,针对设备文件*/ off_t st_size; /* total size, in bytes -文件大小,字节为单位*/ blksize_t st_blksize; /* blocksize for filesystem I/O -系统缓冲块的大小*/ blkcnt_t st_blocks; /* number of blocks allocated -文件实际所占块数,即字节数*/ time_t st_atime; /* time of last access -最近存取时间*/ time_t st_mtime; /* time of last modification -最近修改内容时间*/ time_t st_ctime; /* time of last status change - 最近修改属性时间*/ };

 

4.3 文件类型

 

 

 

4.4 设置用户ID和组ID

 

 

 

 

4.5 文件访问权限

(1)st_mode中除了记录了文件类型之外,还记录了一个重要信息:文件权限。

(2)linux并没有给文件权限测试提供宏操作,而只是提供了位掩码,所以我们只能用位掩码来自己判断是否具有相应权限。

S_IFMT 0170000 文件类型的位遮罩 S_IFSOCK 0140000 scoket S_IFLNK 0120000 符号连接 S_IFREG 0100000 一般文件 S_IFBLK 0060000 区块装置 S_IFDIR 0040000 目录 S_IFCHR 0020000 字符装置 S_IFIFO 0010000 先进先出 S_ISUID 04000 文件的 (set user-id on execution)位 S_ISGID 02000 文件的 (set group-id on execution)位 S_ISVTX 01000 文件的sticky 位

S_IRWXU 00700 文件所有者权限的 掩码

(用这个掩码会得到一个8进制的数字,用来表示权限) S_IRUSR 00400 文件所有者具可读取权限 这些不能当作掩码 S_IWUSR 00200 文件所有者具可写入权限 S_IXUSR 00100 文件所有者具可执行权限

S_IRWXG 00070 文件组权限的 掩码

(用这个掩码会得到一个8进制的数字,用来表示权限) S_IRGRP 00040 用户组具可读取权限 S_IWGRP 00020 用户组具可写入权限 S_IXGRP 00010 用户组具可执行权限

S_IRWXO 00007 其他用户权限的 掩码

(用这个掩码会得到一个8进制的数字,用来表示权限)

S_IROTH 00004 其他用户具可写读权限

S_IWOTH 00002 其他用户具可写入权限 S_IXOTH 00001 其他用户具可执行权限

用这样的方式来使用

 

结果: 注意这里是8进制

 

 

 

4.6 新文件和目录的所有权

(1)新文件的组ID可以是进程的有效组ID

.(2)新文件的组ID可以是它所在目录的组ID.

 

4.7 access和faccessat

access函数可以测试得到当前执行程序的那个用户在当前那个环境下对目标文件是否具有某种操作权限。

int access( const char *pathname, int mode);

int faccessat( int dirfd, const char *pathname, int mode, int flags);

mode:

R_OK(读) W_OK(可写) X_OK(可执行) F_OK(文件是否存在)

 

4.8 函数umask

mode_t umask(mode_t mask);

umask与文件权限掩码 umask时权限的的取反的结果

(1)文件掩码是linux系统中维护的一个全局设置,umask的作用是用来设定我们系统中新创建的文件的默认权限的。

(2)umask命令就是用umask API实现的

 

 

umask默认为0022

 

改变umask后,创建6.txt

 

umask()函数的用法:

https://blog.csdn.net/zhuyi2654715/article/details/7540759

用法实例:

umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

 

4.9 函数chmod,fchmod和fchmodat

 

关于权限为S的解释

https://blog.csdn.net/awhip9/article/details/77774693

 

4.10 粘着位

设置:

 

改变为:

 

不用管,现在这种技术已经不用了

可以参考我的博客:

https://blog.csdn.net/qq_40732350/article/details/82283919

4.11 函数chown,fchown,fchownat和lchown

int chown( const char *path, uid_t owner, gid_t group);

int fchown( int fd, uid_t owner, gid_t group);

int lchown( const char *path, uid_t owner, gid_t group);

int fchownat( int dirfd, const char *pathname, uid_t owner, gid_t group, int flags);

 

 

4.12 文件长度

 

注意:

用lseek偏移后,一定要再在后面写一些内容,不然偏移无效

 

4.13 文件截断

 

第二章情况:这个方法可以解决lseek只偏移,不写,导致的偏移无效的问题(这里是指在文件尾发生偏移)

 

4.14 文件系统

 

 

 

4.15 函数link,linkat,unlink,unlinkat 和remove

创建:link,linkat,

删除:unlink,unlinkat

移动:remove

int link(const char *oldpath, const char *newpath);

int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags);

int unlink(const char *pathname);

int unlinkat(int dirfd, const char *pathname, int flags);

int remove(const char *pathname); //解除链接

硬链接

    若一个 inode 号对应多个文件名,则称这些文件为硬链接。换言之,硬链接就是同一个文件使用了多个别名。

    硬链接可由命令 link 或 ln 创建。如下是对文件 oldfile 创建硬链接。

link oldfile newfile 

ln oldfile newfile

    由于硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性:

  1. 文件有相同的 inode 及 data block;
  2. 只能对已存在的文件进行创建;
  3. 不能交叉文件系统进行硬链接的创建;
  4. 不能对目录进行创建,只可对文件创建;
  5. 删除一个硬链接文件并不影响其他有相同 inode 号的文件。

软链接

    若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软连接

    软链接就是一个普通文件,只是数据块内容有点特殊。

    软链接有着自己的 inode 号以及用户数据块。

    软链接有如下的特性:

  1. 软链接有自己的文件属性及权限等;
  2. 可对不存在的文件或目录创建软链接;
  3. 软链接可交叉文件系统;
  4. 软链接可对文件或目录创建;
  5. 创建软链接时,链接计数 link count 不会增加;
  6. 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。

参考:

http://www.mamicode.com/info-detail-1582696.html

 

4.16 函数rename和renameat

int rename(const char *oldpath, const char *newpath);

int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);

 

实例:

 

 

4.17 符号链接

为了避开硬链接的一些限制

1.硬链接通常要求链接和文件位于同一文件系统中。

2.只有超级用户才能创建指向目录的硬链接(在底层文件系统支持的情况下)。

符号链接的优点:

1.符号链接以及它指向何种对象并无任何文件系统限制,任何用户都可以创建指向目录的符,号链接。

2.符号链接一般用于将一个文件或整个目录结构移到系统中另一个位置。

注意:

当使用以名字引用文件的函数时,应当了解该函数是否处理符号链接。也就是该函数是否跟随符号链接到达它所链接的文件。

如若该函数具有处理符号链接的功能,则其路径名参数引用由符号链接指向的文件。

否则,一个路径名参数引用链接本身,而不是由该链接指向的文件。

 

文件符号链接循环:

 

 

消除循环的方法:

 

指向的文件不存在时的现象:

 

4.18 创建和读取符号链接

int symlink( const char *oldpath, const char *newpath);

int symlinkat( const char *oldpath, int newdirfd, const char *newpath);

函数创建了一个指向oldpath的新目录项newpath.在创建此符号链接时,并不要求oldpath已经存在(在上一节结束部分的例子中我们已经看到了这一点),并且, oldpath和newpath并不需要位于同一文件系统中。

symlinkat函数与 symlink函数类似,但newpath参数根据相对于打开文件描述符引用的,目录(由fd参数指定)进行计算。如果newpath参数指定的是绝对路径或者fd参数设置了 AT FDCWD值,那么symlinkat就等同于symlink函数。

因为open函数跟随符号链接,所以需要有一种方法打开该链接本身,并读该链接中的名字。readlink和readlinkat函数提供了这种功能。

读取符号链接本身:

ssize_t readlink(const char *path, char *buf, size_t bufsiz);

int readlinkat( int dirfd, const char *pathname, char *buf, size_t bufsiz);

读出的结果就是指向的文件名:

 

 

4.19 文件的时间

 

修改时间(st mtim)和状态更改时间(st ctim)之间的区别。

修改时间是文件内容,最后一次被修改的时间。

状态更改时间是该文件的i节点最后一次被修改的时间。

在本章中我们已说明了很多影响到i节点的操作,如更改文件的访问权限、更改用户ID、更改链接数等,但它们并没有更改文件的实际内容。因为i节点中的所有信息都是与文件的实际内容分开存放的,所以,除了要记录文件数据修改时间以外,还需要记录状态更改时间,也就是更改i节点中信息的时间。

注意,系统并不维护对一个i节点的最后一次访问时间,所以access和stat函数并不更改这3个时间中的任一个。

ls命令按这3个时间值中的一个排序进行显示。

系统默认(用-l或-t选项调用时)是按文件的 ,修改时间的先后排序显示

ls -u选项使ls命令按访问时间排序

ls -c选项则使其按状态更改时间排序

各种函数对访问、修改和状态更改时间的作用

 

 

4.20 函数futimens,utimensat和utimes

更改函数的访问和修改时间

int futimens(int fd, const struct timespec times[2]);

int utimensat(int dirfd, const char *pathname,const struct timespec times[2], int flags);

int utimes(const char *path, const struct timeval times[2]);

 

 

 

4.21 函数mkdir,mkdirat,和rmdir

int mkdir( const char *pathname, mode_t mode);

int mkdirat( int dirfd, const char *pathname, mode_t mode);

int rmdir( const char *pathname);

 

 

4.22 读目录

DIR *opendir(const char *name);

DIR *fdopendir(int fd);

struct dirent *readdir(DIR *dirp); //每次只能读一个文件

int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

void rewinddir(DIR *dirp);

int closedir(DIR *dirp);

long telldir(DIR *dirp);

void seekdir(DIR *dirp, long loc);

 

 

 

4.23 函数chdir,fchdir和getcwd

改变和获取当前进程的工作目录

int chdir(const char *path);

int fchdir(int fd);

char *getcwd(char *buf, size_t size);

 

 

 

4.24 设备特殊文件

unsigned int major(dev_t dev);

unsigned int minor(dev_t dev);

 

 

 

普通文件是没有判断

 

 

 

4.25 文件访问权限位小结

 

 

可以通过chmod设置

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值