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

  • Post author:
  • Post category:linux




Day5



stat/fstat/lstat


#include <sys/stat.h>

  • 用来获取文件的属性,
  • 返回 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)





版权声明:本文为WChQGouge原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。