Unix环境高级编程学习笔记(二)
第四章 文件和目录
本章将描述文件系统特征和文件性质
1、stat、fstat和lstat函数
原型:#include<sys/stat.h>
int stat(const char* restrict pathname, struct stat *restrict buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char* restrict pathname, struct stat *restrict buf); 若成功返回0,出错返回-1
注:lstat与stat的不同,当命名文件是一个符号链接时,lstat返回符号链接的有关信息,而stat返回引用文件的信息。
struct stat{
mode_t st_mode;
ino_t st_ino;
dev_t st_dev;
dev_t st_rdev;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
off_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
blksize_t st_blksize;
blkcnt_t st_blocks;
};
2、文件类型:包括普通文件、目录文件、块特殊文件、字符特殊文件、FIFO、套接字、符号链接。 文件类型信息包括在stat结构的st_mode字段,可用以下宏检测文件类型:
S_ISREG():普通文件;S_ISDIR():目录文件;S_ISCHR():字符特殊文件;S_ISBLK():块特殊文件;S_ISFIFO():管道或FIFO;S_ISLNK():符号链接;S_ISSOCK():套接字。 注:头文件:<sys/stat.h> 参数是st_mode
由于POSIX.1允许实现将进程间通信对象(如消息队列和信号量等)表示为文件,所以有一些对应宏用于测是:S_TYPEISMQ():消息队列;S_TYPEISSEM():信号量;S_TYPEISSHM():共享存储对象。注:Linux没有把他们实现为文件,所以没啥用。
3、设置用户Id和组ID
与进程相关的id:实际用户id、实际组id(我们实际上是谁)、有效用户id、有效组id、附加组id(用于文件访问权限检查)、保存的设置用户id、保存的设置组id(由exec函数保存),通常:有效用户id等于实际用户id,有效组id等于实际组id。
每个文件都有所有者(st_uid)和组所有者(st_gid)。可以在st_mode中设置一个特殊标志,使“当执行这个文件时,将进程的有效用户id设置为所有者id”,这叫做设置用户id,同理有设置组id。例如:passwd程序就使用了设置用户id。。。可用S_ISUID和S_ISGID宏测试设置用户id和设置组id。
4、文件访问权限
9个访问权限位:S_IRUSR:用户读;S_IWUER:用户写;S_IXUSR:用户执行; S_IRGRP:组读;S_IWGRP:组写;S_IXGRP:组执行; S_IROTH:其他读 S_IWOTH:其他写 S_IXOTH:其他执行。(注:关于文件访问权限的意义,在之前的博客已写过,在此不再赘述。)
5、新文件和目录的所有权:新文件的用户id设置为进程的有效用户id,组id设置为:(1)进程的有效组id;(2)所在目录的组id。
6、access函数:按实际用户id和实际组id进行访问权限测试。用于验证实际用户能否访问1个文件。
原型:#include<unistd.h> int access(const char* pathname, int mode); mode:R_OK(测试读权限),W_OK(测试写权限),X_OK(测试执行权限),F_OK(测试文件是否存在) 注:这些标志可以进行或运算,来自头文件<unistd.h>
7、umask函数:为进程设置文件模式创建屏蔽字,并返回以前的值,无出错函数。
原型:#include<sys/stat.h> mode_t umask(mode_t cmask) 返回以前的文件模式创建屏蔽字,其中参数cmask是S_IRUSR等9个常量之一或按位或的结果。
说明:任何在文件模式创建屏蔽字中为1的位,在文件mode中的对应位一定被关闭。
8、chmod和fchmod函数:更改现有文件的访问权限
原型:#include<sys/stat.h>
int chmod(const char* pathname, mode_t mode);
int fchmod(int filedes, mode_t mode); 成功返回0,失败返回-1
mode可以使用的参数:1、上文的9个文件访问常量 2、S_IRWXU、S_IRWXG、S_IRWXO、S_ISUID(设置用户id)、S_ISGID(设置组id)、S_ISVTX(保存正位(粘住位))
9、粘住位:如果对一个目录设置了粘住位,则要更名和或删除该目录下的文件必须满足以下条件之一:拥有此文件;拥有此目录;是超级用户。 一般来说,/temp目录就设置了粘住位。
10、chown、fchown和lchown函数:可用于更改文件的用户id或组id
原型:#include <unistd.h>
int chown(const char* pathname, uid_t owner, gid_t group);
int fchown(int filedes, uid_t owner, gid_t group);
int lchown(const char* pathname, uid_t owner, gid_t group); 成功返回0,失败返回-1 lchown:当是符号链接时,lchown改变符号链接本身的所有者,而不是该符号链接指向的文件。
若owner或 group参数的值为-1,则对应的值不变。
11、文件长度:stat结构成员st_size表示以字节为单位的文件长度。此字段只对普通文件、目录文件和符号链接有意义。 stat的st_blksize字段:文件IO较合适的块长度 st_blocks:实际512字节数量。
du -s core : 报告该文件的st_blocks值 wc -c core:用于统计文件中的字节数 (这一段讲述了关于文件空洞问题)
12、文件截短:
原型:#include<unistd.h> int truncate(const char* pathname, off_t length);
int ftruncate(int filedes, off_t length); 成功返回0,失败返回-1
将现有的文件长度截短为length长度,若length长于原来长度,则会产生空洞。
13、文件系统:i节点记录了文件的大部分信息:链接计数(stat的st_nlink成员)、文件类型、文件访问权限等等。只有两项信息放在目录项中:文件名和i节点编号。
两个目录想指向同一个i节点叫做硬链接(nlink_t)、符号链接(S_IFLNK)
14、link、unlink、remove和rename函数
创建一个指向现有文件的链接的方法是使用link函数:#include<unistd.h> int link(const char* existingpath, const char* newpath); 成功返回0,失败返回-1
此函数创建一个新目录项newpath,它引用现有的文件exitingpath(若已存在则报错)。 硬链接
为了删除一个目录项,可以调用unlink函数:#include<unistd.h> int unlink(const char* pathname); 成功返回0,失败返回-1
如果pathname是符号链接,unlink删除符号链接,不会删除引用文件。
我们可以用remove函数解除对一个文件或目录的链接:#include<stdio.h> int remove(const char* pathname); (对文件remove等价于unlink,对目录remove等价于rmdir,这个函数是ISO C指定的)
文件或目录用rename函数更名:#include<stdio.h> int rename(const char* oldname, const char* newname); 成功返回0,失败返回-1
15、符号链接: 硬链接的不足:1)链接和文件必须位于同一文件系统中;2)只有超级用户才能创建指向目录的硬链接 当使用以名字引用文件的函数时,应当了解该函数是否处理符号链接。
16、symlink和readlink函数:
symlink函数创建一个符号链接:#include<unistd.h> int symlink(const char* actualpath, const char* sympath); 创建指向actualpath的新目录项sympath,并不要求actualpath已经存在。
因为open函数跟随符号链接,所以要有一种方法打开该链接本身:#include<unistd.h> ssize_t readlink(const char* restrict pathname, char* restrict buf, size_t bufsize);
17、文件时间:st_atime:文件数据最后访问时间; st_mtime:文件数据最后修改时间; st_ctime:i节点状态最后更改时间。
18、utime函数:更改一个文件的访问和修改时间。
原型:#include<utime> int utime(const char* pathname, const struct utimbuf *times);
struct utimbuf{
time_t actime;
time_t modtime;
} times是NULL则设置当前时间。
19、mkdir和rmdir函数:创建目录和删除目录
原型:#include<sys/stat.h> int mkdir(const char* pathname, mode_t mode);
#include<unistd.h> int rmdir(const char* pathname); 用于删除一个空目录。
20、读目录:
#include<dirent.h>
DIR *opendir(const char* pathname); 返回值:若成功返回指针,若出错返回null
struct dirent *readdir(DIR* dp); 返回值:若成功返回指针,若出错返回null
void rewinddir(DIR* dp);
int closedir(DIR* dp); 返回值:若成功返回0,若出错返回-1
long telldir(DIR *dp); 返回值:与dp关联的目录中的当前位置
void seekdir(DIR* dp, long loc);
struct dirent{
ino_t d_ino;
char d_name[NAME_MAX + 1];
DIR结构是内部结构,上述6个函数用这个内部结构保存当前正被读的目录的有关信息。
}
注意:程序清单4-7用到了函数path_alloc(),但是程序中没定义,编译无法通过。我的解决方法是自己定义一个path_alloc(),简单方便。
char*path_alloc(int* size)
{
char *p = NULL;
if(!size) return NULL;
p = malloc(256);
if(p)
*size = 256;
else
*size = 0;
return p;
} 程序清单4-7用到了opendir,readdir,closedir。
21、chdir、fchdir和getcwd函数
进程通过调用chdir和fchdir函数可以更改当前工作目录:#include<unistd.h> int chdir(const char* pathname); int fchdir(int filedes); 这两个函数分别用pathname或打开的文件描述符来指定新的当前工作目录。 注意:当前工作目录是进程的一个属性,所以chdir函数不会影响别的进程。
#include<unistd.h> char* getcwd(char* buf, size_t size); 得到完整路径名。
22、设备特殊文件:(1)、系统中与每个文件名关联的st_dev值是文件系统的设备号,只有字符特殊文件和块特殊文件才有st_rdev值。
转载于:https://www.cnblogs.com/Just-do-it110/archive/2011/07/30/2121949.html
Unix环境高级编程学习笔记(二)相关推荐
- Unix环境高级编程学习笔记(七) 多线程
线程概述 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(process ...
- Unix环境高级编程学习笔记(一)
第二章 文件I/O 1.文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用,文件描述符是一个非负整数. Unix shell使用文件描述符0表示标准输入,1表示标准输出,2表示标准出 ...
- Unix环境高级编程学习笔记(五)
第七章 进程环境 1.main函数:int main(int argc, char *argv[]) 2.进程中止: 正常中止:(1)从main返回;(2)调用exit;(3)调用_exit或_Exi ...
- UNIX环境高级编程 学习笔记 第十六章 网络IPC:套接字
socket的设计目标之一:同样的接口既可以用于计算机间通信,也可以用于计算机内通信.socket接口可采用许多不同的网络协议进行通信,本章讨论限制在因特网事实上的通信标准:TCP/IP协议栈. 套接 ...
- 文件和目录(二)--unix环境高级编程读书笔记
在linux中,文件的相关信息都记录在stat这个结构体中,文件长度是记录在stat的st_size成员中.对于普通文件,其长度可以为0,目录的长度一般为1024的倍数,这与linux文件系统中blo ...
- 《UNIX环境高级编程》笔记 第五章-标准IO库
1. 流和FILE对象 在第三章的系统调用都是围绕文件描述符fd的.但是标准I/O库函数操作则是围绕流进行的.当使用标准I/O库打开或创建一个文件时,使用一个流与一个文件关联. 当打开一个流时,标准I ...
- linux信号(二)--unix环境高级编程读书笔记
1.信号集 在linux中,可以用一个称为信号集的数据类型 sigset_t,来表示所有的被阻塞信号的一个集合.对这个集合的操作函数有: #include <signal.h>int s ...
- 高级IO(一)--UNIX环境高级编程读书笔记
在前面学习了文件IO,标准IO和终端IO,现在学习高级IO,UNIX中怎么有这么多的IO. 1.非阻塞IO 可以将系统调用分为两类:低速系统调用和其他.低速系统调用是可能会使进程永远阻塞的一类系统调用 ...
- 《UNIX环境高级编程》笔记 第十三章-守护进程
1. 概念 守护进程(daemon)是生存期长的一种进程.它们常常在系统引导装入时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的. Linux的大多数服务就是用守护进程实现 ...
最新文章
- javascript-对混合字母/数字数组进行排序
- jsp中jsp中群发邮件群发邮件
- 制造工业中的机器学习应用:I概览
- BizTalk 10034 错误
- 重学java基础第十四课:java特性和优势
- 听力技巧-4大难点讲析
- 聊聊V8引擎的垃圾回收
- 金山pdf阅读器 独立版V10.1.0.6683
- 怎样把小米手机便签内容转存到百度网盘中去?
- 图像处理之:最大类间方差法法进行图像二值化处理
- loadrunner—集合点rendezvous
- spring boot火车票预订系统毕业设计-附源码091029
- 跟我学-域名解析故障排查技巧
- java设计ui界面(用户登录)
- 二维码制作软件那个好用?
- 推荐5款热门脑图软件!
- 深度学习 lr_scheduler 简易的warmup装饰器
- 不需要密码卸载Symantec Endpoint Protection的步骤
- 微信小程序入门-音乐播放器
- 14年磨一剑,蚂蚁金服全面开放有何阳谋?