Unix_Linux操作系统-笔记Day5(文件)

Day5

stat/fstat/lstat

#include

  • 用来获取文件的属性,
  • 返回 0 成功, -1 失败

int stat(const char *path, struct stat *buf);

  • path 需要文件路径

int fstat(int fd, struct stat *buf);

  • fd 需要打开后的文件描述符

int lstat(const char *pathname, struct stat *buf);

stat/fstat 会跟踪链接目标,而lstat不跟踪链接目标

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;     /* blocksize 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
           };
S_ISREG(m)  is it a regular file?
S_ISDIR(m)  directory?
S_ISCHR(m)  character device?
S_ISBLK(m)  block device?
S_ISFIFO(m) FIFO (named pipe)?
S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)
S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

S_IFMT     0170000   bit mask for the file type bit field
S_IFSOCK   0140000   socket
S_IFLNK    0120000   symbolic link
S_IFREG    0100000   regular file
S_IFBLK    0060000   block device
S_IFDIR    0040000   directory
S_IFCHR    0020000   character device
S_IFIFO    0010000   FIFO
S_ISUID     04000    set-user-ID bit
S_ISGID     02000    set-group-ID bit (see below)
S_ISVTX     01000    sticky bit (see below)

S_IRWXU     00700    owner has read, write, and execute permission
S_IRUSR     00400    owner has read permission
S_IWUSR     00200    owner has write permission
S_IXUSR     00100    owner has execute permission

S_IRWXG     00070    group has read, write, and execute permission
S_IRGRP     00040    group has read permission
S_IWGRP     00020    group has write permission
S_IXGRP     00010    group has execute permission

S_IRWXO     00007    others (not in group) have read,  write,  and
                     execute permission
S_IROTH     00004    others have read permission
S_IWOTH     00002    others have write permission
S_IXOTH     00001    others have execute permission

练习2:使用stat函数,获取文件的属性,显示出文件的类型和权限
homework

struct tm *localtime(const time_t *timep);

  • 使用一个记录秒数据的
struct tm {
               int tm_sec;    /* Seconds (0-60) */
               int tm_min;    /* Minutes (0-59) */
               int tm_hour;   /* Hours (0-23) */
               int tm_mday;   /* Day of the month (1-31) */
               int tm_mon;    /* Month (0-11) */
               int tm_year;   /* Year - 1900 */
               int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
               int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
               int tm_isdst;  /* Daylight saving time */
           };

练习3:获取文件的最后访问时间,最后修改时间,最后属性修改时间
homework

access

int access(const char *pathname, int mode);

  • 测试当前用户对文件的访问权限
  • pathname 文件路径
  • mode
    • F_OK 是否存在
    • R_OK 是否有读权限
    • W_OK 是否有写权限
    • X_OK 是否有执行权限
  • 返回值 0是 -1否

umask

mode_t umask(mode_t mask);

  • 设置并获取权限屏蔽码,(给文件设置权限时,会受权限屏蔽码约束)功能与umask命令一样,一旦设置成功,新创建的文件解不会有mask中的权限
  • 返回值 旧的权限屏蔽码
  • 注意 该权限屏蔽码只对当前进程有效,进程结束后变成默认

chmod/fchmod

int chmod(const char *pathname, mode_t mode);

int fchmod(int fd, mode_t mode);

  • 修改文件的权限
  • 返回值 成功0 失败-1
  • 注意 不受权限屏蔽码的约束

truncate/ftruncate

int truncate(const char *path, off_t length);

int ftruncate(int fd, off_t length);

  • 修改文件的大小,如果文件的大小
  • 返回 0 成功 -1 失败

link/unlink/remove/rename

int link(const char *oldpath, const char *newpath);

  • 创建硬链接文件.硬链接指向的是文件的内存,因此当链接目标被删除后依然能访问文件内容

int unlink(const char *pathname);

  • 删除硬链接文件
  • 注意 普通文件就是硬链接数量为1的文件,当把一个文件的硬链接数删除到0时,这个文件就被删除了

int remove(const char *pathname);

  • 删除文件,该函数时标准库中的删除文件函数,底层调用了unlink系统调用

int rename(const char *oldpath, const char *newpath);

  • 文件重命名

symlink/readlink

int symlink(const char *target, const char *linkpath);

  • 创建软连接(目录文件只能创建软连接)
  • oldpath 链接目标
  • newpath 链接文件
  • 返回 0 成功 -1 失败

ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

  • 读取软链接文件的内容而非链接目标(open打开软连接文件是打开目标文件)
  • path 链接文件的路径
  • buf 读取数据存储位置
  • bufsiz 读取多少个字节
  • 成功读取的字节数

mkdir/rmdir

  • 返回值 0 成功 -1 失败

int mkdir(const char *pathname, mode_t mode);

  • 创建目录,目录一定要有执行权限,否则无法进入

int rmdir(const char *pathname);

  • 删除空目录,非空无法删除

chdir/fchdir/getcwd

char *getcwd(char *buf, size_t size);

  • 获取当前进程的工作目录,工作目录是指当不加路径信息时,创建/打开是从哪个目录下查找工作目录默认是程序所在的目录

int chdir(const char *path);

  • 修改进程的工作目录
  • 返回值 0 成功 -1 失败

int fchdir(int fd);

  • 修改进程的工作目录
  • fd 被open打开的目录文件的fd
  • 返回值 0 成功 -1 失败

opendir/fdopendir/closedir/readdir/rewinddir/telldir/seekdir

DIR *opendir(const char *name);

  • 打开一个目录流
  • 返回值 目录流(链表)

DIR *fdopendir(int fd);

  • 使用文件描述符获取目录流,fd必须是目标文件的

struct dirent *readdir(DIR *dirp);

  • 从目录流中读取一个文件结点的信息
struct dirent {
               ino_t          d_ino;       /* Inode number */
               off_t          d_off;       /* Not an offset; see below */
               unsigned short d_reclen;    /* Length of this record */
               unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* Null-terminated filename */
           };
d_type:
DT_BLK      This is a block device.
DT_CHR      This is a character device.
DT_DIR      This is a directory.
DT_FIFO     This is a named pipe (FIFO).
DT_LNK      This is a symbolic link.
DT_REG      This is a regular file.
DT_SOCK     This is a UNIX domain socket.
DT_UNKNOWN  The file type could not be determined.

int closedir(DIR *dirp);

  • 关闭目录流

void rewinddir(DIR *dirp);

  • 把文件目录流的位置指针调整到开头

long telldir(DIR *dirp);

  • 获取当前目录流的位置指针在第几个文件结点

void seekdir(DIR *dirp, long offset);

  • 调整当前目录流的位置指针
  • offset 只能是telldir的返回值

作业1 实现ls -l的功能
homework

struct passwd *getpwnam(const char *name);

  • 根据用户id获取用户名

struct group *getgrgid(gid_t gid);

  • 根据组id获取组名

作业2 实现rm -rf功能(删除非空目录)
homework

   /* Inode number */
           off_t          d_off;       /* Not an offset; see below */
           unsigned short d_reclen;    /* Length of this record */
           unsigned char  d_type;      /* Type of file; not supported
                                          by all filesystem types */
           char           d_name[256]; /* Null-terminated filename */
       };

d_type:
DT_BLK This is a block device.
DT_CHR This is a character device.
DT_DIR This is a directory.
DT_FIFO This is a named pipe (FIFO).
DT_LNK This is a symbolic link.
DT_REG This is a regular file.
DT_SOCK This is a UNIX domain socket.
DT_UNKNOWN The file type could not be determined.



`int closedir(DIR *dirp);`
- 关闭目录流

`void rewinddir(DIR *dirp);`
- 把文件目录流的位置指针调整到开头

`long telldir(DIR *dirp);`
- 获取当前目录流的位置指针在第几个文件结点

`void seekdir(DIR *dirp, long offset);`
- 调整当前目录流的位置指针
- `offset` 只能是telldir的返回值


> 作业1 实现`ls -l`的功能
> [homework](./code/homework/ls.c)
> >`struct passwd *getpwnam(const char *name);`
> > - 根据用户id获取用户名 
> >
> > `struct group *getgrgid(gid_t gid);`
> > - 根据组id获取组名
> 
> 作业2 实现`rm -rf`功能(删除非空目录)
> [homework](./code/homework/rm.c)



你可能感兴趣的:(笔记)