一、获取文件的元数据(meta data)
通过read write可以对文件的内容进行读写。
但是今天我们要操作的是文件的元数据(文件的属性信息)
day08$ls -l hello
-rw-rw-r-- 1 tarena tarena 0 8月 9 09:17 hello
文件的类型
文件的权限
文件的硬链接数
属主
属组
文件的大小
时间
文件的链接
分为两种 硬链接和软链接
每个文件有且仅有一个自己的inode。
硬链接的两个文件有同一个inode。
如何为一个文件创建硬链接?
ln 源文件 链接文件
如何创建软链接文件?
ln -s 源文件 链接文件
如何使用程序获取文件的元数据?
使用stat(2)获取文件的元数据
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
功能:获取文件信息
参数:
path:指定了文件的名字。
buf:用来存储这个文件的元数据。
返回值:
0 成功
-1 错误 errno被设置
struct stat 这个结构体中有哪些成员,需要了解
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection*/
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; /*blocksize for file system I/O */
blkcnt_t st_blocks; /*number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
举例说明 获取文件的元数据 代码参见 pstat.c
时间的问题。系统记录的是从1970年1月1日0:0:0开始的一个秒数。需要将这个长整型的数转换为字符串格式。
ctime(3)
#include <time.h>
char *ctime(const time_t *timep);
功能:将时间的整数值转换为字符串格式
参数:
timep:指定要转换的长整型的数。
返回值:
NULL 错误
非空 转换后的字符串的首地址
关于用户的问题,用户看到的是文件的名字,而系统管理中使用的是用户的id,数字。
在程序中输出的是数字,但是需要转为字符串格式,方便用户的使用。那如何根据用户的id,找到用户的名字?
使用到函数getpwuid(3)
#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
功能:过去passwd文件中的一条记录
参数:
uid:指定用户的uid
返回值:
指向匹配uid的记录的首地址
NULL 没有找到匹配的记录或者错误的产生。
如果是错误产生 设置errno
struct passwd {
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
在linux系统中用户的信息存放在/etc/passwd文件中
root:x:0:0:root:/root:/bin/bash
tarena:x:1000:1000:tarena,,,:/home/tarena:/bin/bash
以:分隔的七列
第一列:用户的名字
第二列:是否有密码? x有密码
第三列:用户的id。 uid
第四列:用户的组id。 gid
第五列:用户的注释信息
第六列:用户的工作主目录
第七列:用户登陆成功启动的程序
需要将gid转换为组名
getgrgid(3)
#include <sys/types.h>
#include <grp.h>
struct group *getgrgid(gid_t gid);
功能:获取组文件的一条记录
参数:
gid:指定用户组的id
返回值:
NULL 没有找到匹配的记录或者错误产生 如果错误产生errno被设置
返回一个地址
struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};
文件权限的处理
S_ISREG(m) is it a regular file?
S_ISDIR(m) directory?
S_ISCHR(m) character device?
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
st_mode& S_IRWXU 得到的是文件拥有者对文件的权限。
000,111,000,000
000,100,000,000
000,010,000,000
000,001,000,000
作业:编写代码实现ls -l filename的功能。
编译生成可执行文件pls。
二、文件夹的操作
linux操作系统下一切皆文件。文件夹也是文件的一种。
drwxrwxr-x 2 tarena tarena 4096 8月 9 14:57 dir
对文件夹读写操作。
什么是文件夹的内容?
文件夹的内容,就是文件夹里的文件或文件夹。
rwx
r 读
w 写
x 通过
使用程序来访问文件夹的内容。
opendir(3) closedir(3) readdir(3)
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
功能:打开一个文件夹
参数:
name:指定了要打开的文件夹的名字
返回值:
NULL 错误 errno被设置
返回一个指针,指向文件夹流的指针。
DIR FILE
closedir(3)
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
功能:关闭文件夹
参数:
dirp:opendir(3)的返回值
返回值:
-1 错误 errno被设置
0 成功
readdir(3)
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
功能:从文件夹读取数据
参数:
dirp:opendir(3)的返回值。
返回值:
返回一个地址
如果到达了文件的末尾,NULL被返回,errno不变
如果错误产生,NULL被返回,errno被设置
struct dirent{
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /*length of this record */
unsigned char d_type; /* type of file; not supported
by all file system types */
char d_name[256]; /* filename */
};
举例说明 编写代码实现浏览指定文件夹下的所有文件
代码参见 dir_op.c
position
作业的补充:
如果filename是普通文件,将普通文件的元数据输出。
如果filename是文件夹,将文件夹里的所有的文件的元数据输出
三、文件操作的杂项
getcwd(3)
access(2)
chdir(2)
mkdir(2)
umask(2)
rmdir(2)
unlink(2)
link(2)
symlink(2)
rename(2)
remove(3)
chmod(2)
到此 ,文件和文件系统结束了。
进程管理
总结:
一、获取文件的元数据
链接文件
用户 属组
二、文件夹的操作
权限 文件夹的内容
三、文件操作的杂项