基础IO(总结)

本文详细介绍了C语言中的文件接口,包括fopen、fread、fwrite、fseek和fclose等函数的使用,以及系统调用如open、read、write、lseek和close的功能和参数。此外,还探讨了文件描述符的概念、分配规则和内核理解,重定向的原理和接口,以及动态库与静态库的生成和使用。最后,阐述了软链接和硬链接的区别和应用场景。
摘要由CSDN通过智能技术生成

一.C语言中的文件接口

1.fopen

在这里插入图片描述
path:带有路径的文件名称(如果不带路径,打开的文件默认是在当前路径下)
mode:打开文件的方式

r :只读方式打开;文件流指向文件起始位置
r+ :可读写方式打开;文件流指向文件起始位置
w :文件存在:则截断(清空文件内容)文件;文件不存在,则创建一个新文件;
w+ :可读可写的方式打开。文件存在:则截断(清空文件内容)文件;文件不存在,则创建一个新文件;
a:追加写。当前文件不存在,则创建文件;当前文件存在,则将文件流指针指向文件末尾进行写。
a +:可以读,也可以追加写。如果文件不存在,则创建文件;读的位置被初始化到文件的头;但是追加写的时候,从文件的末尾开始追加写

返回值:
成功:返回文件流指针 FILE*
失败:返回NULL;

2.fread

在这里插入图片描述ptr:将从文件中读到的内容保存到ptr指向的内存空间中(空间需要合法,即要申请空间)
size:定义从文件读的时候,一个块是多大,单位字节(通常定义为一字节)
nmemb:期望读多少块
stream:文件流指针

返回值:
返回成功读入的文件块的个数

3.fwrite

在这里插入图片描述
参数:
ptr:往文件内写的内容
size:定义往文件中写的时候,一个块是多大,单位字节(通常定义为一字节)
nmemb:期望写多少块
stream:文件流指针

返回值:
返回成功写入到文件块的个数

4.fseek

在这里插入图片描述
作用:移动文件流指针的位置
参数:
stream:文件流指针
offset:偏移量
whence:将文件流指针偏移到什么位置
SEEK_SET:文件头部
SEEK_CUR:当前文件流指针的位置
SEEK_END:文件末尾

返回值:
成功:0;
失败 :-1;

5.fclose

在这里插入图片描述
stream:文件流指针
关闭文件流(关闭文件)

二.系统调用的文件接口

1.open

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
参数:
pathname:要打开或创建的目标文件
flags:打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算。构成flags
O_RDONLY:只读打开
O_WRONLY:只写打开
O_RDWR:读,写打开
(这三个选项必须指定一个且只能指定一个)
O_CREAT:若文件不存在,则创建它。此时需要mode选项,来指定新文件的访问权限
O_APPEND:追加写

mode:当创建新文件时,指定创建文件的权限:传递一个八进制数字(例:0664)
返回值:
成功:新打开的文件描述符
失败:-1;

2.read

ssize_t read(int fd, void *buf ,size_t count);
参数:
fd:文件描述符
buf:将buf指向的内容写到文件当中去
count:期望写多少字节

返回值:返回写入字节的数量

3.write

ssize_t write(int fd, const void *buf ,size_t count);
参数:
fd:文件描述符
buf:将从文件中读到的内容写到buf指向的空间中去(需要提前开辟空间)
count:期望读多少字节

返回值:返回读到字节的数量

4.lseek

off_t lseek (int fd, off_t offset,int whence);
参数:
fd:文件描述符
offset:偏移量,单位字节
whence:偏移的位置
SEEK_SET:文件头部
SEEK_CUR:当前文件流指针的位置
SEEK_END:文件末尾
返回值:
成功:返回偏移量的位置,单位字节
失败:-1;

5.close

int close(int fd);
关闭文件描述符

三.文件描述符

是一个正数,没有负数
可以在/proc/[进程号]/fd 文件夹下查看,对应的就是它的文件描述符
在这里插入图片描述
0,1,2对应的物理设备一般是:键盘,显示器,显示器

1. 文件描述符分配规则

最小未使用原则
在这里插入图片描述

2. 从内核理解文件描述符

struct task_struct
文件描述符在内核当中本质上就是task_struct结构体中的一个结构体指针files所指向的结构体struct files_struct中的结构体指针数组fd_array的数组下标

一个进程最多打开多少个文件描述符

解答:
1.系统当中针对一个进程打开的文件描述符的数量是有限的
2.通过ulimit -a可以查看“open files”的大小,而“open files”的大小就是限制一个进程可以打开的文件描述符的数量
3.我的机器中看到的“openfiles”的大小是100001,也就是意味着我的机器创建出来的进程最大可以打开的文件数量是100001
4.open fiels”的大小并不是没有办法改变。可以通过 ulinit -n [数字] 进行改变 e.g:ulimit -n 10000
就是将一个进程打开文件描述符的数量改为了10000
在这里插入图片描述
在这里插入图片描述

四.重定向

1 重定向的符号

> :清空重定向
> >:追加重定向

2 重定向的接口

int dup2(int oldfd,int newfd);

作用:将newfd的值重定向为oldfd,即newfd拷贝oldfd
参数:oldfd/newfd均为文件描述符

成功:
1.关闭newfd
2.让newfd指向old对应的syruct file*结构体
失败:
1.如果oldfd是一个(无法/无效)的文件描述符,则重定向失败:newfd没有变化
2.如果oldfd和newfd的值相等,则什么事情都不干

3. 从内核角度理解重定向

文件描述符就是内核当中 fd_array数组的下标

在这里插入图片描述
在原程序中加入 dup(fd,1);
在这里插入图片描述
一号数组的下标指向了文件描述符fd

五.动态库&静态库

什么是库:静态库和动态库都是程序代码(二进制文件)的集合。一般为了方便将程序提供给第三方使用,就是将程序编写成库文件提供给第三方(用户)使用
好处:不会泄露公司的源码;调用者不必关心内部的实现,只需要关注如何使用即可。

1.动态库

特征:
windows下:没有前缀,后缀为dll
linux下:前缀为lib,后缀为.so
生成动态库:
使用gcc/g++ 编译器增加两个命令行参数 -fPIC -shared
生成动态库的代码中不需要包含main函数(程序入口函数)

配置一个简单的动态库来理解如何使用:
第一步:生成动态库
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
第二步:使用动态库
在这里插入图片描述

在这里插入图片描述
编译可执行程序的时候依赖动态库
-L【path】:指定动态库所在的路径
-l【动态库的名称,需要去掉前缀和后缀】:指定编译可执行程序的时候,依赖的动态库是哪个

第三步:配置环境变量
按照前俩个步骤,运行时会报错
原因:需要配置动态库环境变量
在这里插入图片描述
配置 LD_LIBRARY_PATH环境变量
LD_LIBRARY_PATH:一个库文件的环境变量,在~/.bash_profile或者~/.bashrc文件中
在这里插入图片描述
在这里插入图片描述
运行成功~~

2.静态库

特征:
Windows系统下:没有前缀,后缀为./lib
Linux系统下:前缀为lib,后缀为.a
如何生成静态库文件
第一步:使用gcc/g++将源码编译成为目标程序(.o文件)
第二步:使用ar -rc 命令编译目标程序成为静态库
在这里插入图片描述

在这里插入图片描述
注意:必须使用.o文件进行编译

在这里插入图片描述
在这里插入图片描述
运行成功~~

六.软链接&硬链接

1.软连接

目标文件的快捷方式
生成软链接文件ln -s [源文件] [软链接文件]
注意事项:
1.修改软链接文件,源文件也会被修改,修改源文件,软链接文件也会被改变
2.源文件如果被删除,软链接文件还在的,修改软链接文件。会重新建立源文件,重新建立链接关系(这种情况慎重考虑,如果之前的源文件在程序中作用很大,删除后,通过这种方式新生成的源文件与原来的已经不一样了。可能会导致程序崩溃)
建议:在删除源文件的时候,将软链接文件也一并删除掉,以防后患
在这里插入图片描述
软链接文件和源文件的结点号不同

2.硬链接

目标文件的替身
生成方式ln [源文件] [硬链接文件]

在这里插入图片描述
硬链接与源文件有着相同的节点号,且文件的硬链接数变为了2

多个文件引用同一个inode节点的时候,inode节点内部的引用计数会++
当文件删除的时候,引用计数会–,直到引用计数减为0的时候,才会释放inode节点

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Java IO(Input/Output)是Java编程语言中用于处理输入和输出的基础库。它提供了一种方便的方式来读取和写入数据,从而与外部世界进行交互。 Java IO库包含多个类和接口,用于在不同的场景下处理输入和输出。这些类和接口可以分为字节流(Byte Stream)和字符流(Character Stream)两种类型。 字节流主要用于处理二进制数据,而字符流则用于处理文本数据。 常用的字节流类有: - InputStream和OutputStream:用于读取和写入字节数据。 - FileInputStream和FileOutputStream:用于读取和写入文件。 - BufferedInputStream和BufferedOutputStream:提供了缓冲功能,以提高读写的效率。 常用的字符流类有: - Reader和Writer:用于读取和写入字符数据。 - FileReader和FileWriter:用于读取和写入文本文件。 - BufferedReader和BufferedWriter:提供了缓冲功能,以提高读写的效率。 除了字节流和字符流之外,Java IO还提供了一些其他的类和接口,用于处理特定类型的输入和输出。例如: - DataInputStream和DataOutputStream:用于读写基本数据类型及字符串。 - ObjectInputStream和ObjectOutputStream:用于读写Java对象。 - PrintWriter:用于格式化输出。 在使用Java IO时,通常需要使用try-catch语句来捕获可能抛出的异常,例如IOException。 总结起来,Java IO是Java编程语言中用于处理输入和输出的基础库,提供了字节流和字符流两种类型的处理方式,并且还包含其他一些类和接口,用于处理特定类型的输入和输出。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星星21211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值