在学习C语言的阶段里,学过了文件操作——(C语言文件操作)Linux里,“一切皆文件的思想” ,更是围绕着文件进行操作。下面来说说Linux下的文件操作。

目录

《一》系统调用接口

《二》相关概念

《三》文件系统

《四》动态库和静态库


  • 《一》系统调用接口

在C语言里的fopen  fread  fwrite fclose都是C标准库的的函数——库函数
    但是Linux的IO操作的open close read write lseek  是系统调用接口。这是前面说《进程》的时候一个图。

以下接口要带上<fcntl.h>这个头文件

  • 接口1>int open(const char * pathname,int flags, mode_t mode)     返回值是文件描述符

pathname:文件名称
    flags:参数选项/控制字:它们用 | 隔开。
    必选
    O_RDONLY        以只读方式打开文件
    O_RDWR            以可读写方式打开文件
    O_WRONLY        以只写方式打开文件
    可选
    O_APPEND        读写文件从文件尾部开始移动,所写入的数据追加到文件尾            重定向>>
    O_TRUNC          若文件存在并且以可写的方式打开时,此标志会将文件长度清为0,而原来存于该文件的资料也会消失        重定向>
    O_CREAT           若路径中的文件不存在则自动建立该文件
    O_EXCL              如果与O_CREAT同时设置,此指令会去检查文件是否存在,文件若不存在则建立该文件,否则将导致打开文件错误。此外,若O_CREAT与O_EXCL同时设置,并且将要打开的文件为符号连接,则将导致打开文件失败
     mode                   如果需要open创建文件,mode是给这个创建的文件一个默认权限的。

  • 接口2>ssize_t write (int fd, const void * buf, size_t count);

fd:文件描述符
    buf:要写入的数据
    count:写入数据的长度
    返回值:实际写入的长度 失败,-1

  • 接口3>ssize_t read(int fd, void * buf, size_t count);

返回值 实际读取的字节,失败:-1
    fd:文件描述符
    buf:要读取的数据存入的位置
    count:读取数据的长度

  • 接口4>off_t lseek(int fd, off_t offset, int whence);

fd             表示要操作的文件描述符
    offset        是相对于whence(基准)的偏移量
    whence         可以是SEEK_SET(文件指针开始),SEEK_CUR(文件指针当前位置) ,SEEK_END为文件指针尾
    返回值:        文件读写指针距文件开头的字节大小,出错,返回-1
当我们打开一个空文件时,默认情况下文件指针指向文件流的开始。write和read函数本身自带移动文件指针的功能,当我write、read  n个字节后,文件指针会从文件流的开始自动向后移动n位。所以当我们用lseek显式的将文件指针移动后,那么再去read/write时就是从移动过后的位置开始的。


所以我们可以用这个接口来扩展文件大小、获取文件大小、用lseek构建空洞文件(空洞文件就是这个文件中有一段是空的。我们打开一个文件后,用lseek往后跳过一段,再write写入一段,就会构成一个空洞文件。)

  • 《二》相关概念

1>文件描述符
    进程对文件的管理:描述 + 组织
    描述:数组的下标
    组织:结构体数组;描述符就是结构体数组的下标,通过下标找到文件描述信息,进行对文件的操作
    分配规则:遵循最小未使用的下标。
2>文件流流指针 FILE*
    文件流指针与文件描述符的关系
        文件流指针这个结构体中封装了文件描述符作为成员变量
        文件流指针包含了缓冲区。普通文件不具备刷新缓冲区的功能,只有标准输出文件才有这个功能

3>文件重定向
    改变描述符下标所对应的文件描述信息
   函数:
    int dup2(int oldfd, int newfd);
    成功返回新的文件描述符,失败则返回-1
   newfd来指定新描述符数值,若newfd指向的文件已经被打开,会先将其关闭。若newfd等于oldfd,就不关闭newfd,newfd和oldfd共同指向一份文件



 
提一下dup(oldfd):这个等于创建一个文件描述符也指向这个文件

  操作符:
    >    清空文件原有的内容,将新数据写入    
    >>    将新数据追加写入到文件中

   对之前编写的自主shell进行修改,使其支持输入/输出/追加重定向

//C语言1 //1.获取标准输入2 //2.对输入字符串进行解析(获取程序名称 + 参数)3 //3.创建子进程4 //  程序替换5 //4.进程等待6 7 #include<stdio.h>8 #include<unistd.h>9 #include<stdlib.h>10 #include<fcntl.h>11 #include<string.h>12 char buff[1024] = {0};//输入缓冲13 char* argv[1024];14 int argc = 0;15 void menu(char* buff)//输入菜单16 {17     printf("[top-down@localhost]$");18     fflush(stdout);19     //判断进行回车判定,防止第一个字符就是回车20     if(scanf("%[^\n]*c",buff) != 1)//^\n正则表达式,遇到\n截至,*c(s)表示抛弃剩下的字符(字符串)21     {22         getchar();23     }24     printf("%s\n",buff);25 }26 void explain(char* buff)//对输入字符串进行解析27 {28     char* ptr = buff;29     while(*ptr != '\0')//不到结尾,一直循环30     {31         //当前位置非空白字符32         if(!isspace(*ptr))//isspace() 检测空白字符,制表符、换行、回车、空格等33         {34             argv[argc++] = ptr;//保存字符串地址35             while(!isspace(*ptr) && *ptr != '\0')36             {37                 ++ptr;38             }39         }40         else41         {42             *ptr = '\0';43             ++ptr;44         }45     }46     argv[argc] = NULL;47     int i;48     for(i = 0; i < argc; ++i)49     {50         printf("[%s]",argv[i]);51     }52     printf("\n");53 }54 void create()55 {56     pid_t pid = fork();57     if(pid < 0)58     {59         exit(-1);60     }61     else if(pid == 0)62     {63         int i = 0;64         int flag = 0;65         char* str = ">>";66         for(i = 0; argv[i] != NULL; ++i)67         {68             if(strcmp(str,argv[i]) == 0)69             {70                 flag = 1;71                 break;72             }73         }74         argv[i] = NULL;75         int newfd;76         if(flag == 1)77         {78             if(argv[i+1] == NULL)79             {80                 printf("ERROR!\n");81                 exit(-1);82             }83             else84             {85                 newfd = open(argv[i+1],O_RDWR|O_CREAT,0664);86                 dup2(newfd,1);87             }88         }89         execvp(argv[0], argv);90         close(newfd);91         //防止程序替换失败,直接退出92         exit(0);93     }94     wait(NULL);95 }96 int main()97 {98     menu(buff);99     explain(buff);
100     create();
101     return 0;
102 }
  • 《三》文件系统

a、五大部分:超级块,inode结点位图,数据位图,inode,data
    普通文件和目录:目录也是文件,数据存储的是目录项(文件名和inode节点号)

    例如:    cat file:通过文件名在目录项中获取文件inode结点,通过inode结点再到存储位置,读取文件
    b、软连接和硬链接:ln
        软链接:类似快捷方式,存储的是文件的路径。软连接文件和源文件不是同一个文件,有不同的inode号
        硬链接:类似引用,文件的别名。硬链接文件具有相同的inode结点号

        根据上图更容易理解以下的特性:
                   删除源文件,软连接失效,但是硬链接不影响,只是连接数-1(当一个连接数为0的时候才是真正删除一个文件,否则只是删除目录项)
                    软连接可以针对目录创建,硬链接不可以
                   软连接可以跨分区创建,硬链接不可以
      c、 相关命令:
        fd:查看分区挂载情况
        du:文件占磁盘空间大小

  • 《四》动态库和静态库

    动态链接:生成链接
    静态链接:直接拷贝代码

    I、库 :保存实现函数代码的文件
    II、生成库:需要将所有目标文件集合到一起,生成一个打包后的代码库

    III、 生成动态库:
                    gcc -fPIC -c b.c -o b.o            fPIC:产生位置无关代码
                    gcc --share -o xxx.so            share:生成共享库
        动态库命名:以lib为前缀,以.so为后缀,中间是库名称
    IV、生成静态库:
                    ar(静态库链接器)                cr(create创建 raplace模块替换)
                    ar -cr xxx.a b.o
        静态库命名:以lib为前缀,以 .a 为后缀,中间是库名称

    V、静态库/动态库的链接:
    gcc -o -a -lmy_b
    生成可执行程序时,系统需要的所有库都在指定路径(/lib64)下,系统根据名称进行寻找。
    如果不想自己的库将库放在/lib64,可以指定库查找路径(只针对静态库)。链接的时候,优先是动态库,所以在/lib64目录下不能有相同名称的动态库。
    -L 指定路径
    -l 指定链接的库名称
    动态链接生成的可执行程序,需要动态库的存在,并且存在于指定路劲下,因此最好直接拷贝到/lib84

例如:实现一个动态库
我们先创建我们的函数:

接下来我们需要把写的文件封装成动态库

动态库只能在默认的lib64下,所以我们复制下

接下来我们写一个test.c

现在我们进行链接

a 和 b都是整型的。所以商是 0 。

 ldd 查看链接库

Linux征途——基础IO相关推荐

  1. Linux之基础IO

    目录 一.回顾C文件接口 向文件中写入w 向文件中读取r 向文件中读取追加a 输出信息到显示器 stdin & stdout & stderr C++版本的文件操作演示: 二.系统调用 ...

  2. 【linux】基础IO

    文章目录 一.复习文件相关知识 二.复习C文件相关操作 1.复习知识点 2.复习操作 三.文件的系统调用接口 1.open 2.write 3.read 4.小结 四.文件描述符 1.初步认识 2.两 ...

  3. 【Linux】基础IO -- 磁盘文件系统

    前言 上篇Linux文章,我们学习了打开文件,读写文件等的操作.这些都是针对被打开的文件. 而文件还有没有打开的状态,也就是磁盘文件.本篇博客就将会针对磁盘文件,学习其相关知识. 文章目录 前言 一. ...

  4. 【Linux】基础IO --- 内核级和用户级缓冲区、磁盘结构、磁盘的分治管理、block group块组剖析…

    出身寒微,不是耻辱.能屈能伸,方为丈夫. 文章目录 一.缓冲区(语言级:IO流缓冲,内核级:块缓冲) 1.观察一个现象 2.理解缓冲区存在的意义(节省进程IO数据的时间) 3.语言级缓冲区的刷新策略( ...

  5. 【Linux】基础IO —— 动静态库的制作与使用

  6. 【Linux】基础IO(万字详解) —— 系统文件IO | 文件描述符fd | 重定向原理

  7. 【Linux篇】第九篇——基础IO(系统文件IO+文件描述符+重定向+文件系统+软硬链接)

    ⭐️这篇博客就要开始聊一聊Linux中基础IO相关知识,IO相信大家都不陌生,我们在C/C++中对文件进行读写的操作,也就是文件IO,这篇博客我也会带大家回顾一下.这篇博客还会介绍系统中的文件IO调用 ...

  8. Linux中的基础IO(二)

    Linux中的基础IO(二) 文章目录 Linux中的基础IO(二) 一.基本接口 二.文件描述符 三.文件描述符的分配规则 四.重定向 五.dup2系统调用 六.minishell 一.基本接口 i ...

  9. Linux中的基础IO(一)

    Linux中的基础IO 文章目录 Linux中的基础IO 一.C语言中的文件接口 二.随机读写数据文件 三.文件读写的出错检测 一.C语言中的文件接口 写在前面 计算机文件是以计算机硬盘为载体存储在计 ...

最新文章

  1. HDU - 5876 Sparse Graph 2016 ACM/ICPC 大连网络赛 I题 bfs+set+补图最短路
  2. 【Swift】变量/常量/类型总结
  3. CSS中对字体进行设置
  4. abap 给用户分配事物代码权限_【第五篇】SAP ABAP7.50 之用户接口
  5. 2015《大数据》读者意见征集活动——幸运读者名单
  6. java两个数之间质数求法_Java程序显示两个间隔之间的质数
  7. php larvel https,laravel 解决强制跳转 https的问题
  8. jenkins邮件配置(系统邮件和插件)
  9. 阿里人工智能实验室AIoT总架构,15 年工龄的资深技术专家职场历程自述
  10. R语言【探究时间序列的自相关性】
  11. Win11怎么打开网络发现?Win11启用网络发现教程
  12. 网站使用微软雅黑需要版权吗
  13. 修改putty的缺省值设置
  14. 织梦CMS模板安装教程详细图文
  15. Python爬虫 requests使用post请求分析并登录Chinaunix
  16. 储存卡格式化怎么恢复?给力的操作!
  17. 在华为公司的项目总结
  18. 创建响应式HTML电子邮件
  19. **Django介绍 和 MVT 模式 MVC 模式对比**
  20. Python 编程第一讲:IDE推荐

热门文章

  1. 线性调整率(line regulation )和负载调整率(load regulation)
  2. js编码解码一个蛮有意思的事
  3. 零基础学习vue-01-案例
  4. 用python做频数分析_python实现读取类别频数数据画水平条形图
  5. Django管理后台
  6. 【EOS】DAPP开源项目
  7. tasker_如何通过Tasker Automation将Android设备用作行车记录仪
  8. Eclipse无Tomcat 9.0(安装JST Server Adapters Extensions插件后仍不能添加Tomcat 9.0的一种解决办法)
  9. 郭明錤:苹果最早从今年第四季度开始大规模生产AR设备
  10. android蟒蛇音效,ViPER4Android(蟒蛇音效)