Linux IO基础——文件描述符/inode节点/动态库

文章目录

    • 文件操作
      • 打开文件
    • 文件描述符
    • inode节点
      • 硬链接
      • 软链接
    • 生成静态库
    • 生成动态库

文件操作

打开文件

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

flag:(O_RDONLY,O_WRONLY ,O_RDWR )| ( O_APPEND, O_CREAT )

前面三选一,后面可选。

如果是CREAT表示有就执行正常操作,打开失败则创建文件,需要有第三个参数mode,是创建的文件权限。

	//仅在文件不存在时可以创建并append数据到文件末尾,若存在则打开失败
	int fd =  open("xx", O_RDWR|O_APPEND|O_CREAT|O_EXCL, 0644);
	char* str = "hello write\n";
	write(fd, str, strlen(str));

如果使用O_WRONLY,往已存在的文件里写,不会清空原数据,要加O_TRUNC。

关闭文件
int close(const char *pathname);

文件描述符

操作系统为了管理文件,将文件用 struct_file描述起来,用链表数据结构将结构体组织起来。

进程需要一对多的找到属于进程打开的文件,在PCB里有files_struct这么一个结构,其中有一个指针数组保存着文件表指针,而其数组下标就是文件描述符。

Linux IO基础——文件描述符/inode节点/动态库_第1张图片

查看系统限制最大文件描述符个数:proc/sys/fs/file-max

系统允许最大文件描述符,由内存大小决定

ulimit -a 查看用户级限制的文件描述符个数,可以手动调整

系统默认打开三个文件描述符作为标准输入输出错误。

ctr + D 相当于从键盘输入文件结束标记EOF

一个进程两次打开同一个文件,创建新文件表,不创建v结点表。

子进程继承父进程文件描述符,文件表引用计数+1.

##C库FILE结构和文件描述符
C语言中使用的是文件指针而不是文件描述符做为I/O的句柄.
文件指针指向FILE结构。FILE结构包括一个缓冲区和一个文件描述符值.而文件描述符值是文件描述符表中的一个索引.从某种意义上说文件指针就是句柄的句柄。流(如: fopen)返回的是一个FILE结构指针, FILE结构是包含有文件描述符的,FILE结构函数可以看作是对fd直接操作的系统调用的封装, 它的优点是带有I/O缓存

inode节点

真正的数据是在磁盘上存储,磁盘又是一个分盘面,扇区的设备,常见八个扇区为一块。为了操作系统能够准确定位数据读写位置,引入ionde节点。

inode节点存放了文件block位置信息,和文件字节数等重要的文件信息。

想找一个文件的3步骤,通过文件名映射到inode号,读取inode节点信息,找到文件块位置。

inode节点是用来索引文件的,其自身为了存储一些信息必然也需要占空间。操作系统自动划分一个inode区。

硬链接

Unix支持多个文件名指向同一个inode号码,这样修改文件内容会影响到所有的文件。但是删除一个文件名,不影响其他文件名访问。因为其中利用了引用计数原理。

软链接

软链接更像是快捷方式。为A文件创建一个软链接B,则A B有自己的inode节点,但是B文件的内容是A文件的路径。因此在访问B时就自动导向A,且B依赖于A,A没了B打开报错。

生成静态库

之所以叫做静态,是因为静态库在链接阶段的时候会被直接拷贝一份,复制到目标程序里,这段代码在目标程序里就不会再改变了。

静态函数库对开发者来说还是很有用的,例如你想把自己提供的函数给别人使用,但是又想对函数的源代码进行保密,你就可以给别人提供一个静态函数库文件。

静态库将多个目标文件捆绑,形成一个库文件,对调用者提供服务。

  • 生成静态库:

ar -cr libxx.a xx 是静态库名

nm xx 查看静态库

  • 使用静态库

gcc -L库文件路径 -l库名

objdump -dS 查看可执行文件的汇编形式

生成动态库

也称共享库,linux下后缀是.so,windows是dll。与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用。等到程序运行时,动态库才会被真正加载进来

共享函数库文件必须放在一些特定的目录里,这样通过系统的环境变量设置,应用程序才能正确的使用这些函数库。

  • 生成动态库

gcc -fPIC -shared -o libxx.so

  • fPIC :位置无关代码??

  • shared : 生成动态库.

  • 链接动态库

首先将库文件放在/usr/lib 目录下

gcc -L 库文件路径 -l库名

-L 在编译时告诉编译器库的路径,但在运行时系统是去ld.so.conf.d下去找库的。

方案2:提示找不到动态库时!!

不想将动态库放到/usr/lib,可以将库文件路径加入到环境变量里。
增加一个配置文件在 /etc/ld.so.conf.d/ 下,配置文件中写入库路径
echo pwd > /etc/ld.so.conf.d/xx.conf

ldconfig 刷新配置文件
ldd 可执行文件 #命令查看动态库链接错误

1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib和/usr/lib;

cmake 连接时遇到skipping incompatible,说明版本不兼容,用objdump -p 查看动态库的编译版本发现问题。
指定32位编译器解决问题~
./configure CC=“gcc -m32” CXX=“g++ -m32”

你可能感兴趣的:(linux,linux,数据结构)