(Linux)基础IO

一、文件描述符

1.文件描述符下标

Linux 进程默认情况下会有3个缺省打开的文件描述符,stdin ( 0 ) , stdout ( 1 ) , stderr ( 2 ) 。
分别对应:键盘,显示器,显示器。

文件描述符就是从0开始的整数。操作系统在内存中要创建相应的数据结构来描述目标文件,即file结构体。每个进程都有一个*file指针,指向一张files_struct表,该表包含了一个指针数组,每个元素都是一个指向打开文件的指针。
本质上,文件描述符就是该数组的下标。所以,只要有文件描述符,就可以找到对应的文件。

2.系统调用
① open

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

//返回值:成功返回新分配的文件描述符,出错返回-1并设置errno
//参数:pathname,要打开或创建的文件名,和fopen一样,pathname既可以是相对路径也可以是绝对路径;flags,有一系列常数值可供选择,可以同时选择多个常数用按位或运算符连接起来,所以这些常数的宏定义都以O_开头,表示or;mode,权限。

必选且只能选一个:
•O_RDONLY 只读打开
•O_WRONLY 只写打开
•O_RDWR 可读可写打开
可以同时选一个或多个:
•O_APPEND 表示追加。如果文件已有内容,这次打开文件所写的数据附加到文件的末尾而不覆盖原来的内容。
•O_CREAT 若此文件不存在则创建它。使用此选项时需要提供第三个参数mode,表示该文件的访问权限。
•O_EXCL 如果同时指定了O_CREAT,并且文件已存在,则出错返回。
•O_TRUNC 如果文件已存在,并且以只写或可读可写方式打开,则将其长度截断(Truncate)为0字节。
•O_NONBLOCK 对于设备文件,以O_NONBLOCK方式打开可以做非阻塞I/O(Nonblock I/O)。

② read

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t nbytes);

//参数:fd,文件描述符;buf,缓冲期地址;nbytes,本次读取多少个字节
//返回值:成功,返回实际读到的字节数,若已到文件尾,返回0;失败返回-1

③ write

#include <unistd.h>
ssize_t write(int fd, void *buf, size_t nbytes);

//参数:fd,目标文件描述符;buf,缓冲区指针;len,本次读取,期望写入多少字节的数据
//返回值:成功,返回实际写了多少个字节的数据;失败返回-1 或 返回值小于nbytes时,内核很可能会再次写余下的数据,形成死循环,文件系统写满,系统挂了!

在写实际的文件系统的写操作时一定要注意其返回值,否则可能系统崩溃了。
④ close

#include <unistd.h>
int close(int fd);

//返回值:成功返回0,出错返回-1并设置errno
//参数:fd,要关闭的文件描述符

3.重定向
本来应该输出到显示器上的内容,输出到文件内,称为重定向。常见的重定向有:> , >> , <
① 文件描述符分配规则

0往后第一个空闲下标,分配给文件


关闭标准输出,文件的文件描述符变为fd(1),fd(1)中地址已经变为new_file的地址,输出的消息都将写入new_file文件中

4.缓冲方式
① 行缓冲 \n

往标准输出中写

② 全缓冲

往文件中写

③ 没缓冲

printf , fwrite等库函数会自带缓冲区当发生重定向到普通文件时,数据的缓冲方式由行缓冲变为全缓冲;缓冲区是由C标准库二次加上的
write等系统调用*有自带缓冲区


二、文件系统

1.文件系统结构
① 超级块

  • 文件系统元信息

②iNode区

  • 保存文件元信息

③block区

  • 管理n个block
    这里写图片描述

2.软硬链接
①硬链接

不同文件名访问同一个iNode
通过inode引用另外一个文件

②软链接

通过名字引用另外一个文件

  • 快捷方式:特殊的文件类型,保存了另一个文件的全路径

三、静态库与动态库

1.背景

静态库

发布方便,只需要发布一个可执行程序

动态库

发布时需要带上所有依赖的动态库,更新程序的某个模块时较为方便

2.gcc选项

静态库

本质上是“.o”文件的打包,ar -rc

//静态库 makefile

test:test.c libadd.a
    gcc test.c ./libadd.a -o test
libadd.a:add.o
    ar -rc libadd.a add.o
add.o:add.c
    gcc -c add.c -o add.o
.PHONY:clean
clean:
    rm test libadd.a add.o

动态库

shared :表示生成共享库格式
fPIC :产生位置无关码(position independent code)
库名规则 :libxxx.so

//动态库 makefile

test:test.c libadd.so
    gcc test.c ./libadd.so -o test
libadd.so:add.c
    gcc add.c -o libadd.so -fPIC -shared
.PHONY:clean
clean:
    rm test 

$ ldd test 查看
和库一起编译选项

-L 指定查找路径
-l 库名 库文件的文件路径

3.相关环境变量

运行动态库

拷贝 .so文件到系统共享库路径下
更改LD_LIBRARY_PATH

echo $LD_LIBRARY_PATH
echo 环境变量

猜你喜欢

转载自blog.csdn.net/giraffe_255/article/details/80754696