• 3.系统调用函数,对文件的操作


    系统调用:
    定义:操作系统把它具有的功能列成一张表,然后给每一个功能取一个编号,当用户层需要调用某个系统功能时,只需要向内核发送对应的编号即可。
     1.Linux和Unix系统的绝大多数功能都是通过系统调用形式提供的,不是通过函数形式调用,当需要执行这些功能的时候,可以向内核发送一个编号,那么内核就会把对应的系统调用执行。
     2.系统调用是以标准C语言的形式提供的,但是它不属于C语言.
     3.一般程序员所写的代码都工作在用户态,但系统调用工作在内核态,用户态是不能直接访问内核中的数据,必须经过系统调用才行。
    一切皆文件
     在Unix和Linux系统中基本上把所有的资源都抽象成了文件,包括网络,打印机,串口,鼠标键盘,显示器,都可以像操作文件一样来控制硬件
     文件分类:
      目录文件
      设备文件 /dev
      普通文件
     一般操作文件需要的操作
      打开 读 写 设置 关闭
    常见的文件相关的系统调用

    文件描述符:是一个非负的整数,功能类似于标准C中的FILE*文件指针,它代表内核中一个打开的文件


     打开文件
         int open(const char *pathname, int flags);
         pathname:文件的路径
         flags:
          O_RDONLY 只读
          O_WRONLY 只写
          O_RDWR 读写
          O_CREAT 创建
          O_EXCL 文件已存在,则创建失败
          O_NOCTTY
          O_TRUNC 打开时是否清空
          O_APPEND打开时以追加的方式打开
         返回值:
          文件描述符,是一个无符号整数,这个整数对应一个内核对象,对程序来说它的值是多少无所谓,把它当作操作文件的令牌即可。
          特殊的文件描述符:
           0 标准输入
           1 标准输出
           2 标准错误
             int open(const char *pathname, int flags, mode_t mode);
             mode是用来给文件设置权限的,但是通过mode设置的权限会被权限屏蔽码过滤,权限设置是以八进制方式设置的。
              umask设置,查看权限屏蔽字的
        关闭文件:
            int close(int fd)
            fd:文件描述符
            返回值:0表示成功,1表示失败
        创建文件:
         int creat(const char *pathname,mode_t mode);//底层调用的是open
          pathname:文件路径
          mode:文件权限,会受到文件屏蔽字的过滤,创建文件时候需要设置文件权限 0mmm
          creat是调用open来实现的
          返回值:文件描述符
        写文件:
         ssize_t write(int fd, const void *buf, size_t count);
          fd:文件描述符
          buf:要写入的首地址
          count:希望写入的字节数
          返回值:实际写入的字节数
        读文件:
         ssize_t read(int fd, void *buf, size_t count);
          fd:文件描述符
          buf:数据存放的位置
          count:希望读入的字节数
          返回值:实际读入的字节数
         练习:实现cp命令。
    文本文件的数据读写
     1.结构体以文本形式写入文件中
      a.准备缓存区
      b.把结构体使用sprintf拼接到缓冲区中
      c.把缓冲区里的内容写入文件
     2.从文本文件中读取结构体
      a.准备缓冲区
      b.把数据从文件中读取到缓冲区中
      c.使用sscanf从缓冲区中解析结构变量
    文件位置指针:
     off_t lseek(int fd, off_t offset, int whence);
     fd:文件描述符
     offset:偏移值
     whence:基准值
     返回值:调整后的文件位置指针所在的位置
     lseek 对应 fseek
     ftell 没有对应,lseek(fd,0,SEEK_CUR);就可以实现这个功能,rewind同理
     文件黑洞:lseek是可以把文件位置指针调整到文件的末尾之后的位置,形成的空白的东西叫做文件黑洞,文件黑洞是没有数据的,也不占用硬盘空间,但是回计算在文件大小中。
    标准IO与系统IO
     例子:把所有short的值写入到文件中
     标准IO在进行数据读写时,不会把数据直接写入到文件中,而是先写入缓冲区,减少了进出内核的速度,这样就大大提高了文件的读写速度。
     系统IO在不使用缓冲区的情况下,速度不如标准IO。因此在使用系统IO读写文件时一定要为它分配一块缓冲区,大小最好为一页(4K/4096byte)。




    文件描述符的复制:
     #include <unistd.h>
     int dup(int oldfd);
     oldfd:想要复制的文件描述符
    特殊的几个描述符:
    0 = STDIN_FILENO
    1 = STDOUT_FILENO
    2 = STDERR_FILENO
     返回值:最小的没有使用过的文件描述符
        int dup2(int oldfd, int newfd);
        oldfd:想要被复制的文件描述符
        newfd:指定的文件描述符,如果已经被占用则关闭,再复制



    fcntl
        1.复制文件描述符
        2.获取文件权限
        3.设置文件的权限
        4.用此函数操作硬件设备时,fcntl的功能是由硬件驱动决定的,功能可以自定义


    文件同步
        sync 同步所有打开的文件到磁盘
        fsync 同步指定的文件到磁盘
        fdatasync 同步指定的文件,但是只同步数据


    umask/access
        设置权限屏蔽码,只对当前进程有效
        access 查询文件的权限
            F_OK
            R_OK
            W_OK
            X_OK


    chmod/fchmod/chown/fchown/lchown
        chmod/fchmod 修改文件的权限
        chown/fchown/lchown 修改用户id和组id
            lfunc只对软连接文件有效,不针对目标


    truncate/ftruncate
        文件的截取,把文件多余的内容去掉


    link/unlink/remove
        link创建链接文件,创建的是硬链接
        unlink珊瑚链接,一个普通文件其实就是一块数据区,对应了一个硬链接,当一个文件的链接数减为0的时候这个文件就被删除了,此函数也可以用来删除文件。
        remove用来删除文件,与unlink功能类似
        rename重命名

    symlink/readlink
        symlink 创建软链接
        readlink 读取软链接
            而使用open打开软链接文件,打开的是它的链接目标,所以读取到的不是链接文件的内容


    mkdir/rmdir
        mkdir创建目录,创建的目录要有执行权限,否则无法打开
        rmdir只能用来删除空目录,操作系统没有提供删除非空目录的系统调用。
        练习:实现rm -rf的功能


    目录流的操作
        opendir/fopendir 打开一个目录流 返回DIR*
        readdir    从目录流中读取一个对象 struct dirent*
        closedir 关闭目录流

        seekdir  设置目录流位置
        telldir    返回当前目录流的位置
        rewinddir 把目录流的位置调整到开头


        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 */
               };





        练习:实现ls -l的功能
      




    获取用户组信息getpwuid/getgrgid
        getpwuid:使用用户ID获取用户信息
        struct passwd *getpwuid(uid_t uid);

        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 */
               };


        getgrgid:使用组ID获取组信息
        struct group *getgrgid(gid_t gid);

        struct group {
                   char *gr_name; /* group name */
                   char *gr_passwd; /* group password */
                   gid_t gr_gid; /* group ID */
                   char **gr_mem; /* group members */
               };


    练习
            



    附件列表

    • 相关阅读:
      演示一个简单的Redis队列
      Quartz.net 基于配置的调度程序实践
      阿里云OSS分片上传DEMO
      java基础 -- 关键字static的用法
      java基础 -- 关键字final的用法
      Linux中安装软件和各种常用命令
      python获取网页信息的三种方法
      jquery中获取ajax请求返回数据的方法
      Jquery为动态添加的元素添加事件
      js中时间戳转换成xxxx-xx-xx xx:xx:xx类型日期格式的做法
    • 原文地址:https://www.cnblogs.com/LyndonMario/p/9362273.html
    Copyright © 2020-2023  润新知