十三、文件的权限
测试文件的权限:
int access(const char *pathname, int mode); 功能:测试当前用户对该文件的权限 pathname:要测试的文件路径 mode: R_OK 读权限 W_OK 写权限 X_OK 执行权限 F_OK 测试文件是否存在 返回值:存在权限返回0 否则返回-1
修改文件权限:
int chmod(const char *pathname, mode_t mode); int fchmod(int fd, mode_t mode); 功能:修改文件的权限为mode,mode可以使用提供的宏,或者直接使用一个八进制数表示三组权限 注意:权限都可以修改
文件的权限屏蔽码:
-
当使用open\creat 创建文件时,无论给什么权限创建都会成功,但是系统中记录有一个权限屏蔽码会对用户创建的文件的权限进行过滤屏蔽,最终创建出来的文件权限要除去文件屏蔽码
// 可以通过命令 umask 查看当前用户的权限屏蔽码 // 可以通过命令 umask 0xxx 修改当前终端这一次的权限屏蔽码为0xxx mode_t umask(mode_t mask); 功能:给当前进程设置权限屏蔽码 mask:新的屏蔽码 返回值:旧的屏蔽码 注意:只对当前进程有效 注意:屏蔽码只影响open、creat ,对于chmod、fchmod 不受影响
十四、修改文件大小
int truncate(const char *path, off_t length); int ftruncate(int fd, off_t length); length:想要修改成的文件字节数 成功返回0,失败返回-1 截短末尾丢弃,加长末尾添0
#include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main(int argc,const char* argv[]) { int fd = open("trunc.txt",O_RDWR|O_CREAT|O_TRUNC,0644); if(-1 == fd) { perror("open"); return -1; } // 要映射新文件前,需要让文件大小超过0 才能映射并输入、输出 if(-1 == ftruncate(fd,100)) { perror("ftruncate"); close(fd); return -1; } char* str = mmap(NULL,100,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_FILE,fd,0); if((void*)-1 == str) { perror("mmap"); return 0; } // 往映射后的虚拟内存写入数据 //printf("----%s\n",str); sprintf(str,"hello worldxxxxxxxxxxiid\n"); printf("----%s\n",str); // str[0] = 'a'; // 取消映射 munmap(str,100); close(fd); }
十五、链接文件
Linux的文件系统会把磁盘分区成主要的两大部分
-
inode信息块
-
默认128B,里面主要记录文件的权限、大小、所有者、修改时间等基本信息
-
-
block数据块
-
默认4Kb,记录了文件名和真正的文件数据内容
-
-
每个文件必须拥有一个唯一的inode以及若干个block组成,读取文件需要借助文件所在目录的block中记录的文件inode号,找到该文件的inode,inode中记录了该文件的block位置,从而最终读取文件
什么是软、硬链接文件?
硬链接文件
-
硬链接文件没有自己inode和block,只是在不同的目录下复制了一份源文件的inode信息,可以通过该inode找到同一份源文件的block
软链接文件
-
软链接文件会创建自己的新的inode和block,它的inode也是为了找到自己的block,而在它的block中存储的是链接源文件的文件名和inode信息
区别
-
删除源文件,只是删除源文件的inode块,但是硬链接文件不受影响,而软链接文件就无法访问了
-
当一个文件的硬链接数删除成0时,文件才被真正的删除
-
修改硬链接文件内容,源文件也会被修改;而修改软链接的block,不会改变源文件的内容,反而会让软链接无法找到源文件
-
硬链接不能链接目录,软链接可以
硬链接文件的创建和删除:
int link(const char *oldpath, const char *newpath); 功能:创建硬链接文件 与命令 link \ ln 功能一样 int unlink(const char *pathname); 功能:删除文件的硬链接,文件的硬链接数-1 int remove(const char *pathname); 功能:与unlink一致,都可以删除普通文件以及硬链接文件 注意:如果删除的文件正在被打开,则会等待文件关闭后删除 注意:如果删除的是软链接文件,则会只删除软链接文件本身,而不会对源文件有任何影响,而且没有任何一个可以借助软链接来删除链接对象文件的函数
软链接文件的创建与读取:
int symlink(const char *target, const char *linkpath); 功能:创建软链接文件 对应命令:ln -s ssize_t readlink(const char *pathname, char *buf, size_t bufsiz); 功能:获取到软链接文件自身的block内容,也就是它链接对象的文件名,而不会获取到链接对象的文件内容 如果想要读取链接对象的文件内容,还是通过read\write进行
十六、工作目录
-
工作目录指的是当前进程所在的目录,它是相对路径的起点,在操作文件时,如果没有提供文件的绝对路径信息,那么会操作工作目录下的文件,一般默认下工作目录就是当前进程的目录
char *getcwd(char *buf, size_t size); 功能:获取当前进程的工作路径,相当于命令 pwd int chdir(const char *path); int fchdir(int fd); 功能:修改工作路径,相当于cd
十七、创建、删除、读取目录
int mkdir(const char *pathname, mode_t mode); 功能:创建空白目录 mode:目录的权限,目录必须有执行权限次才能进入 int rmdir(const char *pathname); 功能:删除目录,只能删除空白目录 int chdir(const char *path); int fchdir(int fd); 功能:修改工作路径,相当于cd DIR *opendir(const char *name); DIR *fdopendir(int fd); 功能:打开目录文件 返回值:成功返回目录流指针,失败返回NULL struct dirent *readdir(DIR *dirp); 功能:从目录流对象中读取一条条目信息 注意:读取完一条条目后,会自动的往后移动,只需要再次调用该函数,即可以读下一条目录 返回值:返回该条目录信息的结构指针或者NULL(读取失败或者读到了目录末尾结束) 结构体 struct dirent里面存储了目录中某个文件的信息 struct dirent { ino_t d_ino; /* inode节点号*/ off_t d_off; /* 下一条条目的偏移量 注意是磁盘偏移量,而非内存地址*/ unsigned short d_reclen; /* 当前条目的长度 */ unsigned char d_type; /* 文件类型 */ char d_name[256]; /* 文件名 */ }; d_type的取值: DT_BLK 块设备文件 DT_CHR 字符设备文件 DT_DIR 目录 DT_FIFO 管道文件 DT_LNK 软链接文件 DT_REG 普通文件 DT_SOCK socket文件 DT_UNKNOWN 未知 void rewinddir(DIR *dirp); 功能:复位目录流,设置目录流的位置指针回到开头 long telldir(DIR *dirp); 功能:获取当前目录流的位置 void seekdir(DIR *dirp, long loc); 功能:设置目录流的读取位置,这样可以进行任意条目的获取 int closedir(DIR *dirp); 功能:关闭目录文件