zoukankan      html  css  js  c++  java
  • 基础I/O

     基础IO:

      c库文件IO操作接口:(详细查看c语言中的文件操作函数总结:https://www.cnblogs.com/cuckoo-/p/10560640.html)

        fopen  打开文件  fclose   关闭文件  fread  读取文件  fwrite  写入文件  

        fseek  移动跳转当前读取/写入位置  

        printf    格式化字符串输出到终端  

        printf("%s-%s-%s-%d ", "bite", "good", 666);

        sprintf  格式化字符串,将格式化后的字符串写入一个buff中

        sprintf(buff, "%s-%s-%s-%d ", "bite", "good", 666);

        fprintf   格式化字符串,将格式化后的字符串写入文件中

        fprintf(stdout, "%s-%s-%s-%d ", "bite", "good", 666);

        //stdout 标准输出——显示——linux下一切皆文件

      系统调用I/O函数:

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

          pathname:要打开的文件名称

          flags:标志选项

            必选项:(这三个选项相互冲突,只能选择其中一个)

              O_RDONLY  只读

              O_WRONLY  只写

              O_RDWR   读写

            非必选项:

              O_CREAT  若文件存在打开,不存在则创建

              O_EXCL  与O_CREAT同时用时,若文件存在则报错

              O_TRUNC  若文件存在则将文件长度截断为0

              O_APPEND  追加

          mode:若文件不存在需要创建的时候,用于指定创建的文件权限

          返回值:

            成功:非负整数(文件描述符,后续操作都通过描述符完成)

            失败:-1

      

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

          从buf中想fd所代表的文件写入count个字节的数据

          返回值:返回实际的写入长度,出错返回-1

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

          从fd所代表的文件中读取count字节长度的数据放到buf中

          返回实际读取的数据长度,出错返回-1

        lseek(fd, 0, SEEK_SET)

          跳转fd所代表的文件读写位置至起始位置的0偏移量处

      库函数和系统调用接口之间的关系:上下级调用关系

        库函数时对系统调用的一层封装  

      文件描述符:
        定义:返回一个数字,通过数字来管理文件
        进程通过struct file 结构体来描述打开的文件—使用了struct file* fd——array[]

        文件描述符就是这个数组的下标,操作系统通过file结构体描述文件
        并且将指针添加进入fd_array中,向用户返回这个文件描述信息在数组中的下标

        分配规则:
          最小未使用原则:默认从3开始,因为一个程序在运行时会默认打开3个文件

      文件描述符和文件流指针的关系:

             标准输入  标准输出  标准错误输出  

    文件流指针    stdin    stdout    sterr 

    文件描述符    0       1       2   

        文件指针用于库函数操作IO

        文件描述符用于系统调用接口操作IO

        文件流指针结构体中包含了一个成员就是我们的文件描述符

        文件流指针中还定义了一个缓冲区,我们所说的换行刷新缓冲区,实际就是刷新的这个缓冲区,这

    个缓冲区用于将短小数据组成大数据一次性写入文件,这样可以提高效率(换行刷新缓冲区,只针对标准输

    出),而系统调用则没有这个缓冲区。

       进程对文件的管理方式:先描述,在组织管理

        使用结构体来描述:

          文件标识符(inode结点号)  文件名称

    重定向:
      改变数据流向,将写入指定文件的数据,改变之后写入另一个文件
      重定向值得是描述符的重定向,因为描述符并没有改变,改变的是描述符所对应的文件信息

      1.标准输出重定向:

        原本标准输入读取数据重新定向为从其他文件读取数据

        将原来要输出到标准输出的内容,重定向后输出到指定的其他文件

        <:标准输入重定向

        >:标准输出重定向  清空原有内容后添加新内容

        >>:标准输出重定向  向原有内容下方添加新内容


      dup2(int oldfd, int newfd)
      功能:让newfd指向oldfd所指向的文件;
      如果newfd本身已经打开了文件,则关闭原先打开的文件
      则nwefd和oldfd操作的都是oldfd所指向的文件

    文件系统的理解: 

      文件系统(linux下ext2为例):
      磁盘上的文件管理系统(每一个磁盘分区上都会有一个文件管理系统,除了交换分区)

      分块管理:
      数据块区域
      inode结点区域
        inode结点:包含文件大小;权限;时间;占用块数,链接;文件数据存储地址;
      data_bitmap区域
        记录inode结点哪些是空闲的或者已经使用的
      超级块区域
        文件信息的统筹,以上分块的所有信息

      目录文件:
        记录了目录下文件的信息(文件名+inode结点号)——目录项
      文件存储的过程:
        通过inode_bitmap在inode区域获取空闲的inode结点,通过data_bitamap获取空闲数据块,在inode结点中记录文件
        信息以及数据快位置,并且将文件数据写入到数据块中。将自己的目录项信息添加到所在文件中

      文件读取过程:
        在目录项中通过文件名获取文件inode结点号(文件唯一)通过inode结点号在inode区域找inode区域找到inode结点,
        通过inode结点中的数据块地址信息,在指定数据块读取数据。

      查看inode结点大小:
        sudo dumpe2fs -h /dev/sda1 | grep "Inode size"

      软链接/硬链接(操作一个软/硬链接可以改变原文件)
        ln -s 原文件 创建的软链文件
        是一个独立的文件(像快捷方式)

        ln -h 原文件 创建的硬链文件
        一个文件的名字(目录项),与源文件公用一个inode结点

        ls -i (查看文件inode结点号)
        创建的硬链接文件的结点号与原文件相同
        软链中存储的是文件的路径——针对目录项

        软/硬链接的区别:
          删除源文件,软链接文件将失效;硬链接无影响,链接数-1(一个文件的链接数为0 时才是真正的删除了)
          软链接可以跨分区建立,硬链接不可以
          软链接可以对目录创建,硬链接不可以
          (软链接的操作可以跨分区,硬链接不可以)
      动态库/静态库

        动态库命名:lib前缀 .so是后缀 中间是库名称
        -fPIC //产生位置无关代码(课后调研,查找了解)
        1.gcc -fPIC -c child.c -o child.o
        2.gcc --share child.o -o libmychild.so(生成动态库/共享库)

      静态库命名:lib前缀 .a是后缀 中间是库名称
        gcc -c child.c -o child.o
        ar -cr libmychild.a child.o
        -c 创建静态库
        -r 模块替换

      链接库:
        gcc main.c -o main -lmychild
        -l 指定要链接的库名称(只取库名称)
        库文件有默认的搜索路径:lib/lib64/usr/lib64...

        链接时报错,没有找到库,原因:有默认搜索路径
        1.将库文件放入指定路径下 //根目录下lib64
        2.设置/声明环境变量:
          库文件的链接搜索路径:LIBRARY_PATH = .
          库文件的运行加载路径:LD_LIBRARY_PATH = .export
        3.在gcc生成可执行程序时,直接指定库的搜索路径
          gcc main.c -o main -L . -lmychild

          gcc -L //指定库的链接搜索路径

          gcc -I //指定头文件的搜索路径

        想使用第三方静态库,不能用 gcc 的 -static 选项,因为 -static 选项是生成静态链接可以执行
        程序,所有的库都是使用静态库(但我们只希望这个第三方库使用静态库,而不是所有),因此我们的做法
        是将第三方静态库拷贝到指定路径下,使用-L选项指定库的链接搜索路径那么这时候链接的就是静态库。

  • 相关阅读:
    设计原则
    最小路径和--p64--动态规划
    ssm实现数据库关键信息的动态加载
    最大二叉树--p654--递归构造
    城市天际线--p807
    长url转短url--p535
    从中序与后序遍历中构造二叉树-p106--数组,二叉树遍历
    n皇后问题--p52--回溯
    Markdown(editormd)语法解析成HTML
    NFA的实现
  • 原文地址:https://www.cnblogs.com/cuckoo-/p/11062856.html
Copyright © 2011-2022 走看看