IO函数 (C库 VS Linux文件系统)

15 篇文章 0 订阅

1. 标准 C 库 IO 函数

man 3 fread 查看函数用法

请添加图片描述

2. 标准 C 库 IO 和 Linux 系统 IO 的关系

C 库 IO 调用 Linux 系统 IO, 如 fopen标准库函数调用open系统调用

请添加图片描述

3. 相关概念

  1. 虚拟地址空间
    请添加图片描述

  2. 文件描述符
    请添加图片描述

  3. st_mode 变量
    请添加图片描述

  4. Linux 下文件类型有哪些?

文件类型文件类型标识d_type
普通文件-DT_REG
目录文件dDT_DIR
符号链接lDT_LNK
字符设备cDT_CHR
块设备bDT_BLK
管道pDT_FIFO
套接字sDT_SOCK
未知DT_UNKNOWN

4. Linux 系统 IO 操作

man 2 open 查看open函数帮助

  1. open/ close

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    // 打开一个已经存在的文件
    int open(const char *pathname, int flags);
    /*
    参数:
        - pathname:要打开的文件路径
        - flags:对文件的操作权限设置还有其他的设置
          O_RDONLY,  O_WRONLY,  O_RDWR  这三个设置是互斥的
    返回值:返回一个新的文件描述符,如果调用失败,返回-1
    
    errno:属于Linux系统函数库,库里面的一个全局变量,记录的是最近的错误号。
    */
    
    #include <stdio.h>
    void perror(const char *s);
    /*
    作用:打印errno对应的错误描述
    s参数:用户描述,比如hello,最终输出的内容是  hello:xxx(实际的错误描述)
    */  
    
    // 创建一个新的文件
    int open(const char *pathname, int flags, mode_t mode);
    /* 
    参数:
        - pathname:要创建的文件的路径
        - flags:对文件的操作权限和其他的设置
        - 必选项:O_RDONLY,  O_WRONLY, O_RDWR  这三个之间是互斥的
        - 可选项:O_CREAT 文件不存在,创建新文件
        - mode:八进制的数,表示创建出的新的文件的操作权限,比如:0775
        最终的权限是:mode & ~umask
        0777   ->   111111111
        &   0775   ->   111111101
        ----------------------------
        111111101
        按位与:0和任何数都为0
        umask的作用就是抹去某些权限。
    
        flags参数是一个int类型的数据,占4个字节,32位。
        flags 32个位,每一位就是一个标志位。
    */
    
    // 关闭一个文件描述符
    #include <unistd.h>
    int close(int fd);
    
    
  2. read/ write

    #include <unistd.h>
    ssize_t read(int fd, void *buf, size_t count);
    /*
        参数:
            - fd:文件描述符,open得到的,通过这个文件描述符操作某个文件
            - buf:需要读取数据存放的地方,数组的地址(传出参数)
            - count:指定的数组的大小
        返回值:
            - 成功:
                >0: 返回实际的读取到的字节数
                =0:文件已经读取完了
            - 失败:-1 ,并且设置errno
    */
    
    #include <unistd.h>
    ssize_t write(int fd, const void *buf, size_t count);
    /*
        参数:
            - fd:文件描述符,open得到的,通过这个文件描述符操作某个文件
            - buf:要往磁盘写入的数据,数据
            - count:要写的数据的实际的大小
        返回值:
            成功:实际写入的字节数
            失败:返回-1,并设置errno
    */
    
  3. lseek

    // 标准C库的函数
    #include <stdio.h>
    int fseek(FILE *stream, long offset, int whence);
    
    // Linux系统函数
    #include <sys/types.h>
    #include <unistd.h>
    off_t lseek(int fd, off_t offset, int whence);
    /*
        参数:
            - fd:文件描述符,通过open得到的,通过这个fd操作某个文件
            - offset:偏移量
            - whence:
                SEEK_SET
                    设置文件指针的偏移量
                SEEK_CUR
                    设置偏移量:当前位置 + 第二个参数offset的值
                SEEK_END
                    设置偏移量:文件大小 + 第二个参数offset的值
        返回值:返回文件指针的位置
    
    作用:
        1.移动文件指针到文件头
        lseek(fd, 0, SEEK_SET);
    
        2.获取当前文件指针的位置
        lseek(fd, 0, SEEK_CUR);
    
        3.获取文件长度
        lseek(fd, 0, SEEK_END);
    
        4.拓展文件的长度,当前文件10b, 110b, 增加了100个字节
        lseek(fd, 100, SEEK_END)
        注意:需要写一次数据
    */
    
  4. stat/ lstat

请添加图片描述

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *pathname, struct stat *statbuf);
/*
    作用:获取一个文件相关的一些信息
    参数:
        - pathname:操作的文件的路径
        - statbuf:结构体变量,传出参数,用于保存获取到的文件的信息
    返回值:
        成功:返回0
        失败:返回-1 设置errno
*/

int lstat(const char *pathname, struct stat *statbuf);
/*
	作用:获取一个符号链接相关的一些信息
	参数:
        - pathname:操作的文件的路径
        - statbuf:结构体变量,传出参数,用于保存获取到的文件的信息
    返回值:
        成功:返回0
        失败:返回-1 设置errno
*/
  1. 文件属性操作函数

    //文件属性操作函数
    
    #include <unistd.h>
    int access(const char *pathname, int mode);
    /*
        作用:判断某个文件是否有某个权限,或者判断文件是否存在
        参数:
            - pathname: 判断的文件路径
            - mode:
                R_OK: 判断是否有读权限
                W_OK: 判断是否有写权限
                X_OK: 判断是否有执行权限
                F_OK: 判断文件是否存在
        返回值:成功返回0, 失败返回-1
    */
    
    #include <sys/stat.h>
    int chmod(const char *pathname, mode_t mode);
    /*
        修改文件的权限
        参数:
            - pathname: 需要修改的文件的路径
            - mode:需要修改的权限值,八进制的数
        返回值:成功返回0,失败返回-1
    */
    
    #include <unistd.h>
    #include <sys/types.h>
    int truncate(const char *path, off_t length);
    /*
        作用:缩减或者扩展文件的尺寸至指定的大小
        参数:
            - path: 需要修改的文件的路径
            - length: 需要最终文件变成的大小
        返回值:
            成功返回0, 失败返回-1
    */
    
    #include <unistd.h>
    int chown(const char *pathname, uid_t owner, gid_t group);
    /*
    	作用:修改文件的所有者id和组id
    */
    
  2. 目录操作函数

    #include <stdio.h>
    int rename(const char *oldpath, const char *newpath);
    
    #include <sys/stat.h>
    #include <sys/types.h>
    int mkdir(const char *pathname, mode_t mode);
    /*
        作用:创建一个目录
        参数:
            pathname: 创建的目录的路径
            mode: 权限,八进制的数
        返回值:
            成功返回0, 失败返回-1
    */
    
    #include <unistd.h>
    int chdir(const char *path);
    /*
        作用:修改进程的工作目录
            比如在/home/nowcoder 启动了一个可执行程序a.out, 进程的工作目录 /home/nowcoder
        参数:
            path : 需要修改的工作目录
    */
    
    #include <unistd.h>
    char *getcwd(char *buf, size_t size);
    /*
        作用:获取当前工作目录
        参数:
            - buf : 存储的路径,指向的是一个数组(传出参数)
            - size: 数组的大小
        返回值:
            返回的指向的一块内存,这个数据就是第一个参数
    */
    
    #include <unistd.h>
    int rmdir(const char *pathname);
    /*
    	作用:删除空目录
    	返回值:
    		成功返回0, 失败返回-1
    
  3. 遍历目录

请添加图片描述

// 打开一个目录
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
/*
    参数:
        - name: 需要打开的目录的名称
    返回值:
        DIR * 类型,理解为目录流
        错误返回NULL
*/

// 读取目录中的数据
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
/*
    - 参数:dirp是opendir返回的结果
    - 返回值:
        struct dirent,代表读取到的文件的信息
        读取到了末尾或者失败了,返回NULL
*/

// 关闭目录
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
  1. dup/ dup2/ fcntl

    #include <unistd.h>
    int dup(int oldfd);
    /*
        作用:复制一个新的文件描述符
        fd=3, int fd1 = dup(fd),
        fd指向的是a.txt, fd1也是指向a.txt
        从空闲的文件描述符表中找一个最小的,作为新的拷贝的文件描述符
    */
    
    
    #include <unistd.h>
    int dup2(int oldfd, int newfd);
    /*
        作用:重定向文件描述符
        oldfd 指向 a.txt, newfd 指向 b.txt
        调用函数成功后:newfd 和 b.txt 做close, newfd 指向了 a.txt
        oldfd 必须是一个有效的文件描述符
        oldfd和newfd值相同,相当于什么都没有做
    */
    
    
    #include <unistd.h>
    #include <fcntl.h>
    int fcntl(int fd, int cmd, ...);
    /*
    参数:
        fd : 表示需要操作的文件描述符
        cmd: 表示对文件描述符进行如何操作
            - F_DUPFD : 复制文件描述符,复制的是第一个参数fd,得到一个新的文件描述符(返回值)
                int ret = fcntl(fd, F_DUPFD);
    
            - F_GETFL : 获取指定的文件描述符文件状态flag
                获取的flag和我们通过open函数传递的flag是一个东西。
    
            - F_SETFL : 设置文件描述符文件状态flag
                必选项:O_RDONLY, O_WRONLY, O_RDWR 不可以被修改
                可选性:O_APPEND, O)NONBLOCK
                O_APPEND 表示追加数据
                NONBLOK 设置成非阻塞
        
        阻塞和非阻塞:描述的是函数调用的行为。
    */
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值