linuxbingc(IO)系统调用文件接口重定向静态库&动态库软硬链接简单文件系统

Posted 月屯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linuxbingc(IO)系统调用文件接口重定向静态库&动态库软硬链接简单文件系统相关的知识,希望对你有一定的参考价值。

上一篇

目录

系统调用文件接口

open

#include <stdio.h>
#include<iostream>
#include <fcntl.h>
using namespace std;
int main()
int p= open("1.txt",O_RDWR|O_CREAT,0664);
 if(p<0)
   perror("failed");
   return 0;
 
 cout<<"success"<<p;
  return 0;


write read lseek close



#include <stdio.h>
#include<iostream>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
int main()
int p= open("1.txt",O_RDWR|O_CREAT,0664);
 if(p<0)
   perror("failed");
   return 0;
 
 cout<<"success"<<p<<endl;
//写
 char*r="write success";
 cout<<write(p,r,14)<<endl;
 //重置指针
lseek(p,0,SEEK_SET);
 //读
 char r2[15];
 cout<<read(p,r2,14)<<endl;
 cout<<r2;
  return 0;
close(p);

文件描述符


内核理解文件描符


扩展:一个进程可以打开多少个文件描述符

使用 ulimit -a 查看

这个值是可以改变的,通过 ulimit -n 数字改变

文件描述符和文件流指针的区别

源码

文件流指针
grep "struct" . -R//搜索内容指令

1.查看 /usr/include/中的文件,vim stdio.h中的文件

FILE本质是上面的结构体
2.进入 /usr/include/中搜索

grep "struct _IO_FILE" . -R

3.该结构体存在于/usr/include/libio.h中

解释

1.运行代码

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main()
    struct _IO_FILE* fp = fopen("1.txt", "w+");
    if(fp == NULL)
        perror("fopen");
        return 0;
    

    const char* lp = "hello";
    fwrite(lp, 1, strlen(lp), fp);

    printf("fopen success\\n");
   // printf("_fileno : %d\\n", fp->_fileno);
    while(1)
        sleep(1);
    
    return 0;


相应代码的文件描述符信息

两者联系

struct _IO_FILE…这个结构体是C标准库当中的结构体,而该结构体当中维护的读写缓冲区,就是exit函数会刷新缓冲区的那个缓冲区。

文件流指针对应的结构体 struct _IO_FILE这个结构体内部的成员变量int _fileno(1是标准输出,2标准输入,3错误输出)保存了对应的文件描述符的数值。

重定向

原理

每个文件描述符都是一个内核中文件描述信息数组的下标,对应有一个文件的描述信息用于操作文件,而重定向就是在不改变所操作的文件描述符的情况下,通过改变描述符对应的文件描述信息进而实现改变所操作的文件

重定向的符号

//清空重定向
echo "hello" > 1.txt
//追加重定向
 echo "hello" >> 1.txt

重定向接口

int dup2(int oldfd,int newfd)
作用:将newfd的值重定向为oldfd,划newfd拷贝oldfd 参数:oldfd/newfd均是文件描述符
成功:
1.关闭newfd;
2.让newfd指向oldfd对应的struct file*结构体
失败:
1.如果oldfd是一个非法/无效的文件描述符,则重定向失败;newfd没有变化
2.如果oldfd和newfd的值相等,则什么事情都不干

#include <stdio.h>
#include<iostream>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
int main()
int p= open("1.txt",O_RDWR|O_CREAT,0664);
 if(p<0)
   perror("failed");
   return 0;
 
 //重定向
dup2(p,1);
cout<<"123";

 close(p);

结果:123输入到1.txt中

内核角度理解重定向

静态库&动态库

库:程序代码的集合(二进制文件)

动态库

特征:

win:没有前缀,后缀为dll
linux:前缀为lib,后缀为.so

生成:

使用gcc/g++编译器,(增加两个命令行参数)
-fPIC
-shared
(生成动态库的代码当中不需要包含main函数(程序入口函数)

//print.h
#pragma once
#include <stdio.h>
void Print();


//print.c
#include "print.h"

void Print()
    printf("i am so test\\n");

 gcc -fPIC -shared print.c  -o libPrint.so

补充: vim的命令模式下 :vs …/print.h 进入其他文件

使用

编译可执行程序的时候,依赖动态库-L [path] :指定动态库所在的路径
-l[动态库的名称(去掉前缴和后纱之后的名称)〕﹔指定编译可执行程序时,依赖的动态库是那个。

  1. 依赖程序
//刚才写的print.h地址
//main.c
#include "../print.h"
int main()
  Print();

2.编译可执行程序

 gcc main.c -L .. -lPrint -o print 

3.但是此时可执行程序找不到动态库
方案

1.将动态库放到可执行程序的路径下〔不推荐)
2.配置LD_LIBRARY_ PATH
动态库的环境变量LD_LIBRARY__PATH
推荐大家的方式,公司当中产品在客户机器部署的时候,常用的手段


是修改过程文件生效
3.放到系统库的路径下:/lib64《极力不推荐)
直接 cd/lib64进进去

  1. 执行可执行程序print

静态库

特征:
win:没有前缀。后缀为.lib
linux :前缀为lib。后缀为.a
生成
使用之前的print.h和print.c
1.第一阶段:使用gcc/g++将源代码编译成目标程序(.o)

 gcc -c print.c -o print.o

2.第二阶段:使用ar -rc命令编译目标标程序成为静态库
ar -rc静态库文件名称][目标程序]

ar -rc libPrint.a print.o

3.查看静态库中的目录列表

4.生成可执行程序

//依赖程序main.c
#include "../print.h"
int main()
  Print(); 
 gcc main.c -L .. -lPrint -o static

5.运行 ./static程序
注意:如果直接用源代码编译是不行的
如果在编译可执行程序的时候,使用到了静态库,则该静态库会被编译到可执行程序当中。并没有可执行程序依赖动态库动态库的问题(即可执行程序放到哪里都行)

软硬链接

软连接:目标文件的快捷方式


生成:
ln -s 源文件 软连接文件
注意事项:
1.修改软连接文件,源文件也会被修改
2.源文件如果被删除,软连接文件还在的,修改软连接文件、会重新建立源文件,重新建立链接关系(这种要慎重)
一定在删除源文件的时候,将软链接文件也删除掉〈以防后患)

硬链接:目标文件的替身

ln 源文件 硬连接文件

简单文件系统

ext2文件系统

1.超级块(Super Block)︰存放文件系统本身的结构信息。记录的信息主要有: bolck和inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时同,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
2.GDT,Group Descriptor Table:块组描述符,描述块组属性信息
3.块位图(Block Bitmap) : Block Bitmap中记录着Data Bilock中哪个数据块已经被占用,哪个数据块没有被占用
4.Data blocks存储文件内容的
3和4的关系

5.inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
6.i节点表:存放文件属性如文件大小,所有者,最近修改时间等。(软连接和文件的i节点表相同;对于硬链接多个文件引用同一个inode节点的时候,里面的引用计数会++,当文件删除的时候,在目录中对应的记录删除,引用计数会减减,直到引用计数减为0,才会释放inode节点。)

5和6的关系类型3和4

例子



下一篇

以上是关于linuxbingc(IO)系统调用文件接口重定向静态库&动态库软硬链接简单文件系统的主要内容,如果未能解决你的问题,请参考以下文章

JSF 页面不使用过滤器接口重定向

使用Guava retryer优雅的实现接口重试机制

将 NodeJS 服务器端口重定向到子域或文件夹(amazon ec2)

树莓派/Debian HTTP 到 HTTPS 端口重定向

nginx端口重定向及反向代理

Android 逆向Android 逆向通用工具开发 ( adb forward 网络端口重定向命令 | PC 端逆向程序主函数分析 )