admin管理员组文章数量:1516870
文件属性
文件属性
:我们通过
ls
查到就是文件属性,只不过ls只显示了部分文件属性
学习操作文件属性的 OS API ,可以深入的理解文件
文件属性的OS API
- stat、fstat、lstat
- umask
- chown,fchown,lchown
- link,unlink,remove,rename
- symlink和readlink
- chdir、和getcwd
文件七种类型
z - :普通文件 d :目录文件 c :字符设备文件 s :套接字文件
p :管道文件 l :链接文件 b :块设备文件
1. 普通文件
普通文件根据 存放的内容 的不同,分为:
- 文本文件:存放的都是文字编码
文本编辑器打开后,会将这些文字编码翻译为文字图形
- 纯二进制文件(机器码):里面放的是cpu执行的纯二进制机器码
用文本编辑器打开后,显示的内容无法是错乱的,无法辨识。
其实不管存放的是文字编码,还是机器码,在计算机中存储时,其实都是 以二进制形式 存放的
2. 目录文件
目录是一种特殊的文件,专门用于管理其它文件。
3. 字符设备文件
字符设备文件就是
字符设备驱动程序在上层的表现形式。
当应用程序想要实现对某个字符设备进行读写时,需要调用底层的字符设备驱动程序,上层就需要对接底层的字符驱动程序,字符设备驱动在上层会以“字符设备文件”的形式表现出来,我们通过open、read、write去读写字符设备文件,就实现了和底层字符设备驱动程序的交互。
4. 块设备文件
块设备文件,是块设备驱动程序在上层的表现形式
字符设备与块设备有什么区别?
字符设备: 以字节为单位来操作数据。比如:键盘、鼠标、显示器都等是字符设备。
字符设备的驱动程序,就称为“字符设备驱动程序”
块设备: 块设备存储的数据量往往非常大,为了提高读写效率,都是以块(1024字节)为单位来操作数据。
比如电脑硬盘、移动硬盘、u盘等,凡是涉及大量数据存储的,都是以块为单位来操作数据的,都是块设备。
块设备的驱动程序,就称为“块设备驱动程序”。
底层驱动程序,就分为字符设备驱动和块设备驱动
5.管道文件(FIFO:p)
管道文件,用于实现 不同进程(程序)之间的通信 ,管道是OS提供的一种纯代码层面的通信机制。
数据 数据
A进程 ————> 管道文件 ————>B进程
6.套接字文件(socket)
专门用于 网络通信 的文件
7.符号连接(symbolic link)
其实就是一种 快捷图标 ,背后指向了另外一个文件
这7类文件,其中 普通文件数量最多 ,其次是 目录文件 ,然后才是其它类的文件
用file命令查看可执行文件
- ELF:Linux下可执行文件的格式,Windows下的可执行文件是PE格式
- 64-bit:文件里面的机器指令是64位的
- LSB:小端序,C语言里面有详细介绍大小端序
- executable:明确告诉你,该文件是一个可执行文件
- x86-64:运行的是intel的i386的、64位的cpu
-
dynamically linked, /lib64/ld-linux-x86-64.so.2
程序使用的库是动态链接库,库名叫/lib64/ld-linux-x86-64.so.2 - for GNU/Linux 3.2.0:运行的系统是Linux系统(ubuntu),数字是版本号
- not strippe:程序没有被瘦身,里面包含有各种用于调试用的信息。
-
当这个程序最终发布时,会使用
strip命令为程序瘦身,去除里面的无用信息,让程序变的更小。
获取文件属性的函数:stat、lstat、fstat
- 这三个是兄弟函数,实现的功能相同,只是略微有区别
我们只要先把stat函数搞清楚了,lstat、fstat非常容易理解。
ls命令其实就是调用了这三个函数中的lstat来实现的,我们可以调用lstat函数来自己实现一个ls命令
通过这三个函数的学习,深刻的理解文件各种属性,进而理解了“文件”是个什么东西
1.stat
函数原型
#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>intstat(constchar*pathname,structstat*statbuf);函数功能
功能就是获取文件的属性信息
每个文件的属性信息,都是存在
块设备上、该文件自己的inode节点空间中的。
调用stat函数时,文件系统通过stat给的path,到块设备上索引到该文件的inode节点空间,然后将里面的文件属性信息,读到应用程序的缓存中,如此就得到了文件的属性信息。
文件属性数据中转的过程:
应用缓存 <———— stat函数提供的内核缓存 <———— 驱动程序的缓存 <————— 块设备上的inode结点
应用缓存:调用stat函数的应用在内存中开辟的应用缓存
返回值
调用成功,返回0,失败返回-1,errno被设置。
参数说明
int stat(const char *path, struct stat *buf);
(1)const char *path:文件路径名
(2)struct stat *buf:应用缓存,用于存放读到的文件属性信息
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>voidprint_error(char* str){perror(str);exit(-1);}intmain(){int res=0;//存放返回结果structstat sta={0};//存放应用缓存//int stat(const char *pathname, struct stat *statbuf);
res=stat("mm.txt",&sta);if(res==-1)print_error("stat fail!");//把读入的内容打印printf("%d %lu %d %d %ld %s\n",sta.st_mode,sta.st_nlink,sta.st_uid,\
sta.st_gid,sta.st_size,"mm.txt");return0;}Linux都是以数字形式来管理属性信息的
主函数传参数
#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>voidprint_error(char* str){perror(str);exit(-1);}intmain(int argc,char** argv){//main带参数int res=0;structstat aaa={0};//argc---参数数量if(argc!=2){printf("可执行程序+文件名");exit(-1);}/*获取文件属性*/
res=stat(argv[1],&aaa);//注意取地址,传的是指针if(res==-1)print_error("stat fails!");/*打印文件属性*/printf("%d %ld %u %u %ld %ld %s",\
aaa.st_mode,aaa.st_nlink,aaa.st_uid,aaa.st_gid,\
aaa.st_size,aaa.st_atime,argv[1]);return0;}7类文件都有的属性
ino_t st_ino; /
inode结点号 /
mode_t st_mode;
/* 文件类型和文件权限*/
nlink_t st_nlink; /* 链接数
/
uid_t st_uid; /
文件所属用户ID*/
gid_t st_gid; /* 文件所属组ID
/
off_t st_size; /
文件大小
/
time_t st_atime; /
最后一次访问时间,read*/
time_t st_mtime; /* 最后一次修改时间,write
/
time_t st_ctime; /
最后一次属性修改的时间,如权限被修改,文件所有者(属主)被修改 */
专门给块设备文件用的
-----1:dev_t st_dev; /* 块设备号 */
-----2:blksize_t st_blksize; /* 系统每次按块Io操作时,块的大小(一般是512或1024)*/
-----3:blkcnt_t st_blocks; /* 块的索引号 */
****
专门给字符设备用的
-----dev_t st_rdev; /* 字符设备号(ID) */
ls信息
st_uid—表示文件的所属用户,用户id(用户编号)是唯一的
st_gid----多个用户可以在一起组成一个组,其中的某个用户会担任组长,该用户的用户id,就是整个组的组id
对于普通用户而言,自己一个人就是一组,组员和组长都是自己,所以一般情况下,ls显示文件的所属组时,就是所属用户亲自担任组长的那个组,而且组员就自己一人
st_mode属性
介绍st_mode的目的是,希望通过st_mode的学习,深入理解文件权限这个东西。
关键是理解,而不是记忆
st_mode起到:表示文件类型和指定文件权限的双重作用
st_mode的第一个符号代表文件类型,其他的表示的是“ 文件权限 ”
每三个为一组(rwx rwx r-x)
第一个读权限,第二个写权限,第三个可执行权限
每组第一个:如果是-,表示不能读,如果是r,表示可以读
每组第二个:如果是-,表示不能写,如果是w,表示可以写
每组第三个:如果是-,表示不可以被cpu执行,如果是x,表示可以被执行
三组权限
创建文件的用户;用户组里的其他用户;普通用户
第一组:代表的是文件所属用户,对该文件的操作权限
第二组:代表的是文件所属组里面,其它的组员用户,对该文件的操作权限
第三组:除了所属用户、所属组以外的,其它用户对该文件的操作权限
这里只有root可读写,所以guojiawei没有权限去写文件
三组权限的大小关系
- 正常情况下,所属用户的操作权限 >= 组员用户的操作权限 >= 其它不相干用户的操作权限
把数字打印成字母形式
st_mode为33200,对应的二进制为:1000(文件类型) 000 (设置位)110 110 000(文件权限)
文件类型宏名
为了方便使用,在Linux系统提供的stat.h头文件中,给数字定义了宏名
#define S_IFREG 0100000 代表普通文件
#define S_IFDIR 0040000 代表目录文件
#define S_IFBLK 0060000 代表块设备文件
#define S_IFCHR 0020000 代表字符设备文件
#define S_IFIFO 0010000 代表管道文件
#define S_IFSOCK 0140000 代表套接字文件
#define S_IFLNK 0120000 代表符号链接文件
如何取出12~15位的值,然后用于判断文件的类型
- 使用c语言中的 & 操作即可实现
- 使用屏蔽字0170000(1111000000000000)&st_mode,将0 13清零(屏蔽),留下的12 15
- 系统给这个屏蔽字定义了一个宏名,即#define S_IFMT 0170000
如何快速判断文件类型
/*文件属性自定义*/char file_type ='0';//判断if(S_ISLNK(aaa.st_mode)) file_type='l';elseif(S_ISREG(aaa.st_mode)) file_type='-';elseif(S_ISDIR(aaa.st_mode)) file_type='d';elseif(S_ISCHR(aaa.st_mode)) file_type='c';elseif(S_ISBLK(aaa.st_mode)) file_type='b';elseif(S_ISFIFO(aaa.st_mode)) file_type='p';else file_type='s';printf("\n%c\n",file_type);从数字提取文件权限
文件权限
rwx rwx r-x __________/\_________
文件类型 设置位 | |
* * * * * * * * * * * * * * * *
如图: 4位文件权限,3位设置位,三组文件权限,每组文件权限三位
提取用户权限
#define S_I
R
USR 00400:对应的是0000 000 100 000 000,提取用户读权限
#define S_I
W
USR 00200:对应的是0000 000 010 000 000,提取用户写权限
#define S_I
X
USR 00100:对应的是0000 000 001 000 000,提取用户可执行权限
提取用户组权限
#define S_I
R
GRP 00040 (0000 000 000 100 000)
#define S_I
W
GRP 00020 (0000 000 000 010 000)
#define S_I
X
GRP 00010 (0000 000 000 001 000)
提取其他用户权限
#define S_I
R
OTH 00004 (0000 000 000 000 100)
#define S_I
W
OTH 00002 (0000 000 000 000 010)
#define S_I
X
OTH 00001 (0000 000 000 000 001)
比如提取例子中的st_mode值(33200)中的用户权限
33200(十进制) = 1000000110110000(二进制)
1000 000 110 110 000
&0000 000 100 000 000S_IRUSR
1000 000 110 110 000&0000 000 010 000 000S_IWUSR
1000 000 110 110 000&0000 000 001 000 000S_IXUSR
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>intmain(int argc,char** argv){if(argc!=2){printf("请输入文件路径和文件名");exit(-1);}structstat _buf={0};int res=stat(argv[1],&_buf);//注意取地址//int stat(const char *pathname, struct stat *statbuf);/*打印文件权限--使用移位*/int i;char show_qx[]="rwxrwxrwx";char buf_qx[10]={0};for(i=0;i<9;i++){if(_buf.st_mode &(1<<(8-i))){
buf_qx[i]=show_qx[i];//值为1,&位真}else{
buf_qx[i]='-';}}printf("%s\n",buf_qx);return0;}版权声明:本文标题:文件权限大揭秘:使用函数轻松获取SWF文件属性 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.betaflare.com/biancheng/1773206325a3276860.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论