操作系统——基础IO

基础IO

1.C语言操作文件接口
2.系统调用函数的操作文件接口
3.文件描述符
4.文件描述符&文件流指针的区别
5.重定向
6.静态库&动态库

C语言操作文件接口

FILE* fopen(const char* path, const char* mode);

path:待打开的文件(文件路径 + 文件名称)
mode:以何种方式打开
r:以只读方式打开,当文件不存在的时候,就会打开失败
r+:以读写方式打开,当文件不存在的时候,就会打开失败
w:以只写方式打开,如果文件不存在,则创建文件。如果文件存在就会截断(清空)文件
w+:以读写方式打开,如果文件不存在,则创建文件,如果文件存在就会截断(清空)文件
a:以追加方式打开文件,只支持写,如果文件不存在,则创建文件。当前的文件流指针指向了文件的末尾
a+:以追加方式打开文件,只支持读和写,如果文件不存在,则创建文件。当前的文件流指针指向了文件的末尾
返回值:打开成功返回文件流指针,打开失败返回NULL

size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
ptr:要往文件当中写的内容
size:写入块的大小,单位是字节
nmemb:块的个数,单位是个
	写入的字节数量: size * nmemb
	注意:一般在程序当中使用的时候,是将size设置为1,则nmemb就表示写入的字节数量
	stream:文件流指针

返回值:返回写入成功的块的个数,切记:不是写出成功字节的数量

size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
prt:要将读到的内容保存在哪里
size:每次读块的大小
nmemb:块的个数
stream:文件流指针

返回值:成功读到的块的个数

int fseek(FILE* stream, long offset, int whence);
stream:文件流指针
offset:偏移量
whence:
	SEEK_SET:文件流指针偏移到文件头部
	SEEK_CUR:文件流指针偏移到当前位置
	SEEK_END:文件流指针指向文件末尾位置

在这里插入图片描述

int fclose(FILE* fp);//关闭文件流指针

fopen, fwrite, fread, fseek, fclose这些函数都是库函数,是C库当中提供给程序员调用的函数
open, write, read, lseek, close 这些函数都是系统调用,是操作系统内核为程序员提供的函数

系统调用函数的操作文件接口

int open(const char* pathname, int flags, mode_t mode);
pathname:要打开的文件名称(路径 + 名称)
flags:以何种方式打开
	必须的宏,三个宏有且只能出现一个
		O_RDONLY:只读方式
		O_WRONLY:只写方式
		O_RDWR:读写方式
	可选的宏
		O_APPEND:追加
		O_TRUNC:截断
		O_CREAT:文件不存在则创建
	使用的方式,必须的宏和可选的宏之间使用按位或的方式
	eg. 	O_RDWR | O_CREAT
mode:权限
	新创建出来的文件设置权限
	传参的时候,传递8进制数字就可以了
返回值:
	打开成功,返回大于等于0的数字,是文件描述符
	打开失败,返回-1

O_RDONLY: 八进制的0
O_WRONLY: 八进制的1
O_RDWR: 八进制的2
是按照位图的方式来使用的
eg.O_RDWR | O_CREAT
在这里插入图片描述

ssize_t read(int fd, void* buf, size_t count);
fd:文件描述符,open的返回值
buf:要将读到的内容放到哪里去
count:最带可以读多少个,单位字节
返回值:返回读到的字节数量
ssize_t write(int fd, const void* buf, size_t count);
fd:文件描述符,open的返回值
buf:往文件当中写的内容
count:写的内容的大小
返回值:写成功的字节数量
off_t lseek(int fd, off_t offset, int whence);
fd:文件描述符
offset:偏移量
whence:
	SEEK_SET:文件流指针偏移到文件头部
	SEEK_CUR:文件流指针偏移到当前位置
	SEEK_END:文件流指针指向文件末尾位置
int close(int fd);//关闭文件描述符

文件描述符

1.操作系统会为每一个进程在磁盘当中创建一个以进程号命名的文件夹,在该文件夹下有一个fd文件夹,保存的信息为该进程打开的文件描述符信息

在这里插入图片描述
2.当我们新创建出来一个进程,势必会打开3个文件描述符,分别对应
标准输入(0),标准输出(1), 标准错误(2)

在这里插入图片描述
1.文件描述符其实就是内核当中的fd_array数组下标
2.文件描述符是一个正整数,分配原则为最小未占用原则

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

1.文件流指针式fopen函数返回的,文件流指针是属于C库在维护的
2.文件描述符是open函数返回的,文件描述符是内核在维护的

在这里插入图片描述
1.不同的文件流指针,在C库中会创建不同的struct _IO_FILE,在_IO_FILE结构体当中保存了不同的文件描述符
2.文件流指针当中包含文件描述符
3.操作系统当中广泛存在缓冲区,但是如果针对文件流指针而言的缓冲区,是C库在维护的
exit函数在退出的时候,会刷新缓冲区,就是因为操作的是文件流指针
_exit函数在退出一个进程的时候,不会刷新该缓冲区,是因为该缓冲区是C库在维护的,内核并不知道,所以不会刷新
在这里插入图片描述
文件描述符(文件句柄)泄露问题
当我们打开一个文件,操作系统会给程序分配一个文件描述符,如果在使用完毕之后,没有及时关闭文件,就会造成文件句柄泄露

补充;
一个进程当中最大打开的文件数量是多少?
ulimit -a
1.open files (-n) 1024
2.ulimit -n [num] 0~1023

重定向

在这里插入图片描述
1.命令感受:
清空重定向:“>”
追加重定向:“>>”
eg.echo “123” > 57linux

重定向接口

	int dup2(int oldfd, int newfd);
	oldfd:
	newfd:
1.关闭newfd
		关闭成功:第二步
		关闭失败:重定向失败了
				newfd本身就是一个无效的文件描述符
2.newfd拷贝oldfd的值

动态库和静态库

命令1:ldd[可执行程序] :查看当前程序依赖的动态库文件
C动态库:libc.so.6 =>/usr/lib64/libc.so.6
命令2:file[可执行程序] : 可以查看文件的属性

1.动态库
1.1 生成
gcc/g++
-shared -fPIC
-o后面生成的动态库的名字
前缀:lib
后缀:.so
eg.libabab.so ==> abab称之为动态库的名字
1.2 使用

test.h
	void func();
test.c
	func()
	{
		......
	}

1.编译动态库的源码当中不能出现main函数
2.gcc -shared -fPIC test.c -o libfunc.so

main.c
	#include "test.h"
	func();

编译可执行程序的时候,一定要告诉编译器,我们链接的动态库是哪个!

gcc main.c -o main

指定连接动态库所在的路径
-L[path]
指定连接动态库的名字
-I[库的名称(去掉前缀和后缀的)]

2.静态库
前提知识:
win下的静态库的后缀为 .lib
win下的动态库的后缀为 .dll
2.1 生成
前缀:lib
后缀:.a
libabab.a ==>abab就是静态库的名字
ar -rc lib [名字].a[依赖的文件]
依赖文件不是源文件!而是.o文件!
2.2 使用
main.c
func() /=/=> libfunc.a
gcc main.c -o main -L [path] -l [静态库的名字]
在这里插入图片描述
线性存储方式可能会导致磁盘的利用率降低,产生磁盘碎片
离散存储方式会提高程序对磁盘的利用率

**Block Bitmap : ** 本质是一个位图,每一个比特位表示Data blocks当中的使用情况,如果
比特位为1,则表示占用,如果为0,则表示空闲
**Data blocks : **实际存储文件的blocks区域,这个区域当中,将磁盘分成了不同的小block
**inode Bitmap : ** 本质也是一个位图,每一个比特位表示inode table 当中inode 块的使用情
况,如果比特位为1,则表示占用,如果为0,则表示空闲
**inode Table : ** inode节点的集合,inode节点描述了文件的存储情况(文件在哪些block
块当中存储的)

1.文件的存储
1.1 去Block Bit Map 区域查找空闲的block块,将文件存储在空闲的block块当中
1.2 通过inode BitMap获取空闲块的inode节点,通过inode节点去描述文件在Data Block区域当中存储的位置
1.3 inode+文件名称作为目录的目录项保存下来
2.文件的获取
2.1 通过文件名称和inode节点找到inode对应的文件信息
2.2 在Data blocks 区域当中获取当前文件存储的内容,再进行拼接,拼接完后就是文件的内容了

软/硬链接
软连接:
1. 软链接文件就相当于一个文件的快捷方式
2. ln -s [源文件] /[ 生成的软连接文件/]
3. 软连接文件具有独立的inode 节点号
4. 在删除软连接文件或者软连接文件指向的源文件的时候,一定将两者都删除掉
硬连接:
1. ln [源文件] /[ 生成的硬连接文件/]
2. 源文件和硬连接文件的inode节点号是一模一样的
3.硬连接文件除了和源文件的名称不一样之外,其他的都一样

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值