Unix的文件管理(下)
目录
- access 函数
- 复制文件描述符
- 获取文件的元数据(或者叫做属性)
- 元数据中得到文件类型
- 元数据中得到文件权限
- 元数据中得到相关时间
- 元数据中得到用户信息
- 实现 ls 查看信息功能
access 函数
//需要引入的头文件
#include <unistd.h>
//API如下
// 文件路径 // 访问模式
int access (const char* pathname, int mode);
函数功能
按实际用户ID和实际组ID(而非有效用户ID和有效组ID),进行访问模式测试。
测试调用进程对该文件, 是否可读/可写/可执行, 或者取F_OK,测试该文件是否存在
参数详解
第一个参数 pathname:路径
第二个参数 mode:选择如下 同时可以 | 但是必须先包含R_OK
R_OK:可读
W_OK:可写
X_OK:可执行
返回值
- 成功:
返回0 - 失败:
返回-1
复制文件描述符
dup和dup2是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。
这个过程类似于现实生活中的配钥匙,钥匙相当于文件描述符,锁相当于文件,本来一个钥匙开一把锁,相当于,一个文件描述符对应一个文件,现在,我们去配钥匙,通过旧的钥匙复制了一把新的钥匙,这样的话,旧的钥匙和新的钥匙都能开启这把锁。
对比于 dup, dup2也一样,通过原来的文件描述符复制出一个新的文件描述符,这样的话,原来的文件描述符和新的文件描述符都指向同一个文件,我们操作这两个文件描述符的任何一个,都能操作它所对应的文件。
dup
//需要引入的头文件
#include <unistd.h>
//API 如下
int dup(int oldfd);
函数功能
复制一个文件描述符
参数详解
第一个参数:oldfd 源描述符
返回值
- 成功:
返回新的文件描述符 - 错误:
返回-1,errno被设置为相应的错误码
dup2
//需要引入的头文件
#include <unistd.h>
//API 如下
int dup2(int oldfd, int newfd);
函数功能
复制一个文件描述符
参数详解
第一个参数:oldfd 指定源描述符
第二个参数:newfd 指定新的描述符 如果这个描述符原来是打开的,使用之前先关闭。
返回值
- 成功:
返回新的文件描述符 (newfd) - 错误:
返回-1,errno被设置为相应的错误码
获取文件元数据(属性)
文件有两部分构成 文件的内容 文件的属性。
文件的元数据就是文件的属性
每个文件都有一个对应的i节点,这个I节点里面保存了文件的元数据和所在的硬盘位置。中文译名为"索引节点"。
系统打开文件这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block。
相关命令 查看文件元数据
ls –i 查看I节点
inode 编号 文件的类型 文件的权限 硬链接数 属主 属组 大小 最后修改时间
stat 文件名 查看文件的元数据
相关函数
stat
//需要引入的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
//API 如下
int stat(const char *pathname, struct stat *buf);
函数功能
获取文件的身份信息
参数详解
- 第一个参数 pathname:指定了文件的名字
- 第二个参数 buf:将文件的身份信息存储到buf指定的空间里
返回值
- 成功:
返回 0 - 失败 -1 errno被设置为相应错误码
fstat
//需要引入的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
//API 如下
int fstat (int fd, struct stat* buf);
函数功能
获取文件的身份信息
参数详解
- 第一个参数 fd:文件描述符
- 第二个参数 buf:将文件的身份信息存储到buf指定的空间里
返回值
- 成功:
返回 0 - 失败 -1 errno被设置为相应错误码
元数据结构体
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
- dev_t st_dev; 文件使用的设备号码
- ino_t st_ino; 索引节点号
- mode_t st_mode; 文件对应的模式,文件、目录等
- nlink_t st_nlink; 文件硬链接数
- uid_t st_uid; 所有者用户识别号
- gid_t st_gid; 组织别号
- dev_t st_rdev; 文件设备号
- off_t st_size; 以字节为单位的文件容量
- blksize_t st_blksize; 包含文件的磁盘块大小
- blkcnt_t st_blocks; 该文件所占的磁盘块
- struct timespec st_atim; 最后一次访问的时间
- struct timespec st_mtim; 最后一次修改的时间
- struct timespec st_ctim; 最后一次改变改文件状态的时间
未完待续