3.2文件属性
linux中的各类文件类型
普通文件(-,regual file)
“-”文件标识。
1、文本文件。文件内容由文本构成的文件,文本指的是ASCII字符。文件里内容本质上都是数字。(不管什么文件),文本文件中的数字本身应被理解为这个数字的ASCII码。.c、.h、.txt文件都是文本文件。好处:可以被人读懂和编写。
2、二进制文件
存储的全是数字,不是文字的编码形式。(gcc编译生成的a.out,arm-linux-gcc编译连接生成的.bin)都是二进制文件
3、对比:两者本质上没有任何区别,都是一个文件里面存放数字。区别是理解方式不同,将其当做数字处理就是二进制,按照某种编码格式去解码成文本字符,就是文本文件。
4、linux系统层面是不区分文本文件与二进制文件的。因此我们无法从文件本身准确知道文件属于哪种文件,我们只能通过一些后缀名来标记不同的文件来认识此文件的类型。
5、使用文本文件时,一般用文本文件编辑器去打开它。
目录文件(d,directory)
目录就是文件夹,在linux中是一种特殊文件。是一种特殊文件,存储内容包括文件的路径,文件列表等。linux中有一些特殊API专门来读写文件夹。
字符设备文件(c,character)
块设备文件(b,block)
设备文件对应的是硬件设备,也就是文件虽然在文件系统中存在,但是并不是真正存在于硬盘上的一个文件没事文件系统虚拟制造出来的。成为虚拟文件系统如(/dev,/sys,/proc等)
虚拟文件系统中的文件大多不能或者不用直接读写,而是一些特殊的API产生。
管道文件(p,pipe)
套接字文件(s,socket)
符号链接文件(l,link)
常用文件属性获取
stat、fsta、lstat
struct 指针变量一定是输出型变量,const 修饰的变量一定是输入型变量。
sat a.out 显示a.out文件属性。
stat从文件名得到文属性,其作用就是让内核将需要文件的属性信息结构体的值放入我们传递给stat函数的buf中。
fstat从一个打开的文件的fd得到文件属性。
lstat对于符号链接文件来说:stat与fstat查阅的是符号链接文件指向的文件属性,lstat查阅的是符号链接本身的属性。
struct stat
是内核定义的结构体,在<sys/stat.h>中声明,此结构体中的所有元素加起来就是文件属性信息。
int ret = -1;
struct stat buf;
memset(&buf, 0, sizeof(buf));
ret = stat(NAME, &buf);
if(ret < 0)
{
perror("stat");
return -1;
}
printf("inode = %ld\n",buf.st_ino);
printf("size = %ld bytes\n",buf.st_size);
printf("st_blksize = %ld\n",buf.st_blksize);
stat函数应用案例:
判断文件类型:(-、d、l.....)struct stat 的 st_mode元素
宏操作:S_ISSREG返回1表示文件是普通文件。
int result = S_ISREG(buf.st_mode);
判断文件权限:
st_mode还记录了文件权限。没有文件权限测试的宏操作,只是提供了位掩饰码来判断。
改变文件权限:chmod u-r FILENAME,减去读权限。
S_IR/W/XUSR表示对文件有可读/写/执行权限
int result = ((buf.st_mode) & S_IRUSR) >> 8;//返回1表示有其权限。
文件权限管理
st_mode 本质是一个三十二位的二进制数,每一个位表示一个含义。
文件类型与文件权限都在st_mode中。使用专门的掩码去取出相应的位即可得知相应的信息
ls -l 打印出来的文件列表。
三组rwx分别表示文件的属主对文件的权限(owner,user),文件的属主所在的组(group)对文件的权限,其他用户(other)对文件的权限
属主属于创建文件的用户。但是文件在创建之后可以用chown 来修改文件的属主,还可以chgrp去修改文件所在的组
文件操作时的权限检查规则
a.out去执行,a.out中试图操作文件1.txt,此时怎么判断a.out是否具有对1.txt的某种操作权限:
查看1.txt的9个权限位。(user,group,others),知道a.out对1.txt属于什么身份。查看a.out的属主与其属主所在的组
access函数检测权限设置
在操作某个文件时应先判断当前文件是否有权限对其操作,并提供信息。access函数可以测试当前执行程序的用户在当前环境下对目标文件的权限。
F_OK文件存在,R_OK文件可读,W_OK文件可写,X_OK文件可执行。
chmod与fchmod函数
修改文件各项权限。chmod只有root用户去执行修改。
chown/fchown/lchown
chown用来修改文件属主,chgrp用来修改文件所属的组
umask与文件权限掩码
文件掩码是linux系统中维护的一个全局设置,umask来设置系统中新创建文件的默认权限。
umask0044表示 rw--w--w-;推导过程:0666-0044=0622。4对应r,2对应w,1对应x。
读取目录文件
opendir与readdir
opendir打开一个目录后得到一个DIR类型的指针给readdir使用
readdir函数调用一次就会返回一个struct dirent类型的指针,这个指针指向一个结构体变量,这个结构体变量里面记录了一个目录项(所谓目录项就是目录的一个子文件)
readdir调用一次只能读出一个目录项,想要读出目录中所有的目录项必须多次调研函数。readdir内部会记录哪个目录被读过了。
readdir返回NULL表示已经全部读完了。
dirent结构体
实战演练:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>int main(int argc, char **argv)
{
DIR *pDir = NULL;
struct dirent *pEnt = NULL;
unsigned int count = 0;
if(argc != 2)
{
printf("usage: %s dirname\n",argv[0]);
return -1;
}
pDir = opendir(argv[1]);
if(NULL == pDir)
{
perror("opendir");
return -1;
}while(1)
{
pEnt = readdir(pDir);
if(NULL != pEnt)
{
//还有子文件
printf("子文件:name: [%s].",pEnt->d_name);
count++;
if(pEnt->d_type == DT_REG)
{
printf("是普通文件\n");
}else
{
printf("不是普通文件\n");
}
}else
{
break;
}
}
printf("总文件为:%d.\n",count);
return 0;
}
可重入函数介绍
函数是由可重入与不可重入之分。
readdir函数内部申请了内存并且给我们返回了地址。多次调用readdir并不会重复申请空间,而是使用第一次调用readdir时分配的那个内存。
readdir多次调用时是有关联得,这个关联表明readdir函数是不可重入的。