• Linux基础IO


    目录

    一、C语言中的文件操作接口

    1.foprn:打开文件

    2.fwrite:向文件写入数据

    3.fseek:跳转文件的读写位置

    4.fclose:关闭文件,释放资源

    5.测试文件操作

    二、系统调用IO接口

    1.open:打开文件

    2.write:向文件写入数据

    3.read:向文件读取数据

    4.lseek:跳转文件的读写位置

    5.close:关闭文件,释放资源

    三、文件描述符★

    1.文件描述符的本质

    2.文件流指针FILE *fp与文件描述符int fd的关系

    四、重定向★

    1.标准输出重定向

    2. dup2接口

    五、动态库与静态库

    1.简介

    2.动态库与静态库的生成

    3.动态库与静态库的使用

    3.1生成可执行程序时链接使用

    3.2运行可执行程序时加载使用


    一、C语言中的文件操作接口

    1.foprn:打开文件

    FILE *open(const char *path , const char *mode);

    const char *path:带有路径的要打开的文件名

    const char *mode:文件的打开方式

        r:只读;文件必须存在,否则打开失败

        r+:可读可写;文件必须存在,否则打开失败

        w:只写;文件不存在则会创建文件并打开,文件存在则会清空文件原有内容并打开

        w+:可读可写;文件不存在则会创建文件并打开,文件存在则会清空文件原有内容并打开

        a:追加只写;文件不存在则会创建文件并打开,文件存在则打开;并且写入数据总是会写入文件末尾

        a+:可读追加写;文件不存在则会创建文件并打开,文件存在则打开;并且写入数据总是会写入文件末尾

        b:以二进制方式打开文件,否则默认以文本形式打开文件

    返回值:

    成功,返回FILE*文件流指针(文件在代码中的操作句柄);失败,返回NULL

    2.fwrite:向文件写入数据

    size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

    const void *ptr:要向文件写入的数据的首地址

    size_t size:块大小

    size_t nmemb:块个数

    FILE *stream:fopen返回的文件流指针,表示要将数据写入到哪个文件

    返回值:

    返回实际写入文件的完整块个数(注意不是字节长度);出错返回0。

    3.fseek:跳转文件的读写位置

    int fseek(FILE *stream, long offset, int whence);

    FILE *stream:要操作的文件流指针

    long offset:偏移量;正值,向后偏移;负值,向前偏移

    int whence:标识开始偏移位置

        SEEK_SET:起始位置

        SEEK_CUR:当前读写位置

        SEEK_END:末尾位置

    返回值:

    成功,返回0;失败,返回-1。

    4.fclose:关闭文件,释放资源

    int fclose(FILE *fp);

    返回值:

    成功,返回0;失败,返回-1。

    5.测试文件操作

    int ferror(FILE *stream);

    测试文件的上一次操作是否出错,出错返回真。

    int feof(FILE *stream);

    测试文件读写是否到达文件末尾,到达返回真。

    二、系统调用IO接口

    系统调用IO接口默认都是二进制操作。

    1.open:打开文件

    int open(const char* pathname, int flags);

    int open(const char* pathname, int flags, mode_t mode);

    const char* pathname:要打开的文件的路径名

    int flags:文件的打开方式

    (

    O_RDONLY:只读    O_WRONLY:只写    O_RDWR:可读可写

    以上三种必须包含其一。

    O_CREAT:文件不存在则创建文件;

    O_APPEND:写入数据时以追加方式写入;

    O_TRUNC:打开文件时,清空文件内容。

    例:w方式可表示为:O_WRONIL | O_CREAT | O_TRUNC

    )

    mode_t mode:文件不存在时创建文件所使用的参数(文件的权限);若不需要创建文件,则这个参数可以不要

    返回值:

        成功,返回一个非负整数(文件描述符|文件的操作句柄);

        失败,返回-1。

    2.write:向文件写入数据

    ssize_t write(int fd, const void *buf, size_t count);

    int fd:open打开文件返回的文件描述符,标识要操作的文件

    const void *buf:要写入的数据的首地址

    size_t count:要写入文件的数据的字节长度

    返回值:

        成功,返回实际写入文件的数据长度;

        失败返回-1。

    3.read:向文件读取数据

    ssize_t read(int fd, void *buf, size_t count);

    int fd:open打开文件返回的文件描述符,标识要操作的文件

    void *buf:一块空间首地址,用于存放读取到的数据

    size_t count:要读取的数据长度,单位为字节

    返回值:

        成功,返回实际读取到的数据长度;

        出错,返回-1。

    4.lseek:跳转文件的读写位置

    off_t lseek(int fd, off_t offset, int whence);

    int fd:文件的操作句柄

    off_t offset:偏移量

    int whence:开始偏移位置

        SEEK_SET:起始位置

        SEEK_CUR:当前读写位置

        SEEK_END:末尾位置

    返回值:

        成功,返回当前跳转后的位置相对于起始位置的偏移量(通常跳转到文件末尾位置,就可获取文件长度)

        出错,返回-1。

    5.close:关闭文件,释放资源

    int close(int fd);

    返回值:

    成功,返回0;失败,返回-1。

    三、文件描述符★

    1.文件描述符的本质

    文件描述符:当open打开一个文件时,返回的一个非负整数,它是一个文件的操作句柄。

    那么文件描述符作为一个数字,是如何作为文件的操作句柄来标识文件的?

    文件其实就是一块磁盘空间,给文件写入数据,实际上就是将数据写入到磁盘的指定位置。

    因此当我们要操作一个文件时,必须要明确操作的是那块磁盘的哪个位置的数据。

    ★文件描述符的本质其实就是内核中,文件描述信息指针数组的下标。

    通过文件描述符操作文件,实际上就是在内核中找到进行的files_struct结构体,根据下标在fd_arr描述信息指针数组中找到对应文件的描述信息地址,进行访问文件的描述信息,从而实现标识我们所要操作的文件。

    2.文件流指针FILE *fp与文件描述符int fd的关系

    文件流指针:

    struct FILE*  是库函数的操作句柄

    文件描述符:

    int  fd  是系统调用接口的操作句柄

    库函数与系统调用接口的关系:

    库函数封装了系统调用接口

    所以文件流指针结构体FILE中,其实包含了文件描述符成员。

    四、重定向★

    1.标准输出重定向

    将原本要写入标准输出的数据,不再写入标准输出,而是写入指定文件中。

    例:

    相关知识:

    一个程序运行,会默认打开三个文件:

    标准输入0、标准输出1、标准错误2

    关闭标准输入文件,打开的新文件会优先占据下标较小的空位置,也就是temp.txt对应的文件描述符会是1,那么此时本来要写入标准输出的数据会被写到temp.txt中。

    运行程序后,内容没有打印。

    而是写入到了temp.txt文件中。

    2. dup2接口

    int dup2(int oldfd, int newfd);

    让newfd拷贝oldfd位置的文件描述信息指针,作用相当于让oldfd和newfd都操作oldfd所对应的文件。

    例:

     效果相同,且不需要关闭旧的文件,更加灵活安全。

    五、动态库与静态库

    1.简介

    动态库与静态库:都是针对典型功能已经封装好的接口的打包文件

    程序编译四个阶段:预处理、编译、汇编、链接

    链接方式:

    1)动态链接:

    链接动态库,把库中函数的位置信息记录到可执行程序中。

    2)静态链接:

    链接静态库,将库中用到的代码写入到可执行程序中。

    2.动态库与静态库的生成

    1)将各自的.c代码生成二进制指令

    gcc -fPIC -c file.c -o file.o

    2)打包生成库文件

    动态库:

    gcc -shared file.o -o libfile.so

    静态库:

    ar -cr libfile.a filr.o

    3.动态库与静态库的使用

    3.1生成可执行程序时链接使用

    gcc -l 选项--指定链接库名称

    gcc file.c -o file -lmylibfile

    链接方法:

            1.将库文件放到指定目录下:/usr/lib64/

            2.设置环境变量,将库文件所在路径添加到环境变量中:LIBRARY_PATH=${LIBRARY_PATH}:./

            3.使用gcc -L选项指定库文件默认链接路径(主要针对静态库使用):gcc file.c -o file -L/ -lmylibfile

    3.2运行可执行程序时加载使用

    链接方法:

            1.将库文件放到指定目录下:/usr/lib64/

            2.设置环境变量:LD_LIBRARY=${LD-LIBRARY_PATH}:./

  • 相关阅读:
    JavaScript中的模板直面量
    javaweb学习(一):jsp
    Linux系统下四种nginx安装方法
    BRC铭文NFT铸造质押挖矿系统开发运营
    JavaScript常用事件
    词向量笔记
    算法的复杂度
    【VCED】Jina
    开学季征文 | 新学期给自己的一些小建议
    [数学建模]---1.层次分析法matlab&python
  • 原文地址:https://blog.csdn.net/m0_63020222/article/details/126692435