chmod命令
修改文件权限
- 直接使用数字-----8进制
fd = open(“./new_file.txt”, O_RDWR|O_CREAT,
0664
);指定的0664表示:创建出的文件的原始权限为
rw-rw-r--
-
使用rwx设置权限
-
修改所有权限----chmod a=“权限” 文件名
-
修改一组权限----u=;g=;o=;(注意之间要,)
- 修改一组中的一位权限
-
lstat
-
功能
-
与stat几乎完全一样,都是从块设备上的inode节点空间中读取文件的属性信息
-
但是与stat唯一不同的是,lstat会区分链接文件
当操作的文件是链接文件时:
- stat获取的文件属性是链接文件背后所指向的文件,而不是链接文件的。
- lstat直接显示的是链接文件本身的文件属性
-
什么是链接文件
如需要在系统上维护同一文件的两份或多份副本,除了保存多份单独的物理文件副本之外,还可以采用保存一份物理文件副本和多个虚拟副本的方法。 这种虚拟的副本就称为链接
。链接是目录中指向文件真实位置的占位符。
在Linux中有两种不同类型的文件链接:
- 符号链接(软链接)
- 符号链接就是一个实实在在的文件,它指向存放在虚拟目录结构中某个地方的另一个文件。
- 这两个通过符号链接在一起的文件,彼此的内容并不相同。
- 使用 ln -s 命令创建符号链接时,源文件必须存在,链接文件必须不存在。
- 硬链接
具体操作
创建mm.txt的链接文件pmm
用stat获取mm.txt和pmm的属性
发现stat获取链接文件的属性是其指向的文件;也就是stat获取的pmm属性其实是mm.txt
int main(int argv,char** argc){
if(argv!=2) printf("输入参数个数错误!\n");
struct stat aaa={0};
lstat(argc[1],&aaa);//改用lstat
printf("%d %lu %d %d %ld %s\n",\
aaa.st_mode,aaa.st_nlink,aaa.st_uid,\
aaa.st_gid,aaa.st_size,argc[1]);
return 0;
}
lstat获取的链接文件pmm的属性是自身的
fstat
与stat不同的是,fstat是使用文件描述符来操作的,当你不知道文件路径名,但是你知道指向这个文件的描述符时,就可以使用fstat来操作
int main(int argv,char** argc){
if(argv!=2) printf("输入参数个数错误!\n");
struct stat aaa={0};
int fd=open(argc[1],O_RDWR);
fstat(fd,&aaa);//fstat
printf("%d %lu %d %d %ld %s\n",\
aaa.st_mode,aaa.st_nlink,aaa.st_uid,\
aaa.st_gid,aaa.st_size,argc[1]);
return 0;
}
fstat和stat一样,不区分链接文件
ls背后调用的是lstat
chown命令
功能:用于修改文件的属主
- 修改所属用户-------chown 新的所属用户 文件
- 修改所属组-----------chown :新的组 文件
- 同时修改----------chown 新的所属用户:新的组 文件
unmask
open创建文件给权限777依然不给其他用户写权限
open函数创建新的文件时,如果指定的是0777满级权限的话,实际创建文件权限为0775(rwxrwxr-x)
因为被文件权限掩码做了限制。
111 111 111 (0777)&~000 000 010 (0002)文件权限掩码
(111 111 101)
限制其它用户的写权限
使用umask即可将文件权限掩码改为0
#include <sys/types.h>
#include <sys/stat.h>
//功能:修改文件权限掩码
//参数mask:新的文件权限掩码
//返回值是旧的文件权限掩码
mode_t umask(mode_t mask);
int main(void){ int fd=0; mode_t ret=umask(0); printf("oldUmask=%d\n",ret); fd=open("hhh",O_RDWR|O_CREAT,0777); //mode_t umask(mode_t mask); printf("umask=%d",umask(ret)); return 0; }
符号链接文件的文件大小
- 符号链接文件就是一个快捷键,背后指向了某个文件。
- 符号链接文件的数据,就是所指向文件的文件名,所以它的文件大小指的就是这个名字的字符个数。
pfile -> file.txt
文件截断函数
open时,可以指定了O_TRUNC后,文件里面有数据的话,会将打开的文件截短(清空)为0.
文件截短的函数truncate,它不仅能够将文件截为0,还可以把文件截短为任意长度
#include <unistd.h>
#include <sys/types.h>
// 函数功能----将文件长度截短为length所指定长度
// 返回值---成功返回0,失败返回-1,errno被设置
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
//truncate利用文件路径名操作,ftruncate利用文件描述符操作
truncate("mm.txt",10);
int fd=open("mm.txt",O_RDWR);
ftruncate(fd,3);
截断字符超过文件长度时候:
空洞文件
在一般文件的情况下,对于普通文件来说,文件数据的理论大小 == 在块设备上实际占用的空间大小。
单对于空洞文件来说,文件数据的理论大小 > 在块设备上实际占用的空间大小。
du命令是查看在块设备的实际大小。ls得出的是分配大小-----理论大小
创建空洞文件
int main(void){ int fd=open("./mm.txt",O_RDWR|O_CREAT,0664); lseek(fd,300,SEEK_SET);//注意第三位是设置位 write(fd,"hello",5); return 0;}
文件系统如何管理文件
文件系统就是一个软件代码,属于OS的一部分
文件系统管理文件的逻辑结构——树形结构
对于文件系统来说,目录是非常重要的文件组织节点
-
超级区----负责“块设备”空间的分配和回收
-
inode节点区
-
被划分为了一个个相连的,空间大小相同的inode节点空间
-
每个节点空间被用于存放某个文件的属性信息,每个节点空间大小是固定的(512B)
-
每个节点都有一个节点编号,通过节点编号就可以索引找到inode节点空间
使用
stat
读取文件属性时,struct stat结构体中的st_dev
成员,就是用来存储inode节点编号
的
-
-
数据区-----专门用于存放文件的数据
不是所有的文件都有数据,只有普通文件、目录、链接文件有数据,其它的文件只有属性,没有数据
不同的数据块之间不一定是连续的,块之间使用地址进行相互链接,也即是说每一块都有存放前后块的地址,通过地址就可以找到前后块空间
不同文件的数据区
-
普通文件
如果是文本文件,数据就是文字编码。
如果是纯二进制文件,数据就是机器指令之类。 -
目录文件
目录文件里面放的内容,并不是目录所包含文件的数据,放的只是
所包含文件的基本信息
其中两个信息最重要---------
文件名,文件的inode节点号
-
链接文件
存放的数据很简单,就是所指向文件的文件名