linux--系统文件I/O

目录

一,系统接口

1,open

 2,write

二,文件描述符

1,0&1&2

2,文件描述符是什么东西

3,文件描述符的分配规则

三,缓冲概念

四,重定向

1,重定向的原理

2,重定向的函数

五,文件系统

1,文件是由什么构成的

 2,描述一下创建文件的过程,以及写入1KB的过程

3,删除文件的过程

六,软硬链接

总结


一,系统接口

1,open

函数原型:int open(const char *pathname,int flags)

pathname:要打开或者创建的目标文件。

flags:打开要做什么,基本上有O_WRONLY(只写) O_RDONLY(只读) O_CREAT(创建)O_APPEND(追加)

返回值:成功返回文件描述符

              失败返回 -1;

如下代码:

 2,write

函数原型:

        int write(int _filehandle,const void *_Buf,unsigned int _Maxcharcount)

        _filehandle,文件描述符,_Buf写入的字符,_Maxcharcount字符长度

 相比较于其他接口,均是如此,如read/close/lseek

但对于open的返回值fd为什么是3呢,此时就牵扯到一个文件描述符的概念。

二,文件描述符

1,0&1&2

通过对open的了解,我们知道文件描述符fd是一个整数。

linux系统会默认打开三个接口,0/1/2,这三个接口分别stdin,stdout,stderr,分别对应键盘,显示器,显示器。

而我们也可以使用如下的方式进行输出,通过读0,输出到1和2

void test2()
{
	char buf[1024];
	ssize_t s = read(0, buf, sizeof(buf));
	if(s > 0)
	{
		buf[s] = 0;
		write(1, buf, strlen(buf));
		write(2, buf, strlen(buf));
	}
}

2,文件描述符是什么东西

文件描述符就是从0开始的小整数,当我们打开文件后,就类似与创建进程一样,先描述再组织,使用task_struct描述这个文件的信息,被file_struct管理,使用指针指向数组的下标实现,再通过内核去管理这个文件的信息 ,只要知道这个数组下标,就能找到在内核中对应的信息。

3,文件描述符的分配规则

void test3()
{
	close(1);
	int fd=open("log.txt",O_WRONLY);
    printf("i am printf\n");
	fprintf(stdout,"i am fileskkkk\n");
	fflush(stdout);
	close(fd);
}

 此时我们关闭1号描述符,打开log.txt,使用输出到屏幕,发现屏幕上没有打印任何数据,打开log.txt,发现 i am printf 和i am fileskkkk都写到文件当中了,所以通过这个我们可以看到,

文件描述符会优先分配到未被使用的最小下标。

三,缓冲概念

一般缓冲分为三种:

                        无缓冲(系统接口)

                        行缓冲(常见的对显示器进行刷新数据)(方便人机交互)

                        全缓冲(对文件的写入使用全缓冲)

缓冲一般由语言层提供,os也有缓冲(为了减少对磁盘的访问)

四,重定向

1,重定向的原理

通过上面程序的演示,我们大概可以知道,关闭标准输出,可以将信息输出到文件中,这就是一种重定向,本质是修改文件描述符fd下标对应的struct_file*里面。

我们再来看看下面的程序;

void test4()
{
	close(1);
	int fd = open("myfile", O_WRONLY|O_CREAT, 00644);
	if(fd < 0)
	{
		perror("open");
	}
	printf("fd: %d\n", fd);
	fflush(stdout);
	close(fd);
}

此时,我们发现,本来应该输出到显示器上的内容,输出到了文件myfile 当中,其中,fd=1。这种现象叫做输出重定向。常见的重定向有:>, >>, <,更加说明了这种现象,

2,重定向的函数

使用dup2系统调用

函数原型:

int dup2(int oldfd,int newfd);

dup2(fd,1),如这个一样,用fd覆盖1号文件描述符

这个函数的功能在于覆盖式的把旧的文件描述符给新的文件描述符,两个文件描述符共享权限。

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
int main()
{
	printf("i am printf\n");
	fprintf(stdout,"i am fprintf\n");
	fputs("i am fputs",stdout);
	fork();
	return 0;
}

我们发现此时打印了6条语句,这是因为什么呢,

其原因在于父进程打印完以后,fork创建出子进程,父子进程共享一段代码,父子数据发生写时拷贝,因为进程具有独立性,子进程也执行了三条语句。

所以会输出6行。

但当我们使用如下代码时,

int main()
{
	const char*msg="I am write\n";
	printf("i am printf\n");
	fprintf(stdout,"i am fprintf\n");
	write(1,msg,strlen(msg));
	fork();
	return 0;
} 

会发现打印了5行数据,

这是因为,当我们在往屏幕上打印数据时,会存在一个缓冲的概念,我们使用C库函数打印的时候,会先缓冲到C提供的缓冲区里面,子进程写时拷贝,也会缓冲到缓冲区,由于系统的接口没有缓冲区,所以会直接刷新到屏幕,再把父子进程的缓冲区刷新到屏幕上,所以打印五行数据。

注意:重定向还是不重定向不会更改进程的缓冲方式

           C接口打印两次,osAPI打印1次

五,文件系统

1,文件是由什么构成的

       文件=磁盘文件+内存文件,磁盘文件:文件属性和文件内容的集合,Inode存储文件属性

,磁盘存储文件内容。通过映射inode编号,就能找到文件内容在磁盘的那块存储着。

superblock:存放文件系统的结构信息,主要是存储inode还剩多少,data blocks还剩多少,inode table有那些inode被占用,那些没有,data blocks有哪些block被占用,那些没有。

Group descriptor table:描述块组属性信息

Block Bitmap:使用映射的方式,统计那块空间被占用,那块空间未被占用

Inode Bitmap:使用映射的方式,统计inode编码的占用情况。

Inode Table:索引节点表,存储inode编码

Data Blocks:数据存取块,存储数据的地方,与inode存在映射关系。

 2,描述一下创建文件的过程,以及写入1KB的过程

1,存储属性:使用inodetable,找到inodetable表空闲的节点存储文件的属性信息

2,存储信息,将文件内容存储在Data Blocks对应的空间中,与inode建立映射关系。

3,记录分配情况,在Block Bitmap存储当前内容的存储情况。

4,添加文件名到目录中,文件名和inode之间的对应关系会将文件和文件属性连接起来

写入:

        文件内容写入到datablocks,记录分配情况修改,

        超级块更改修改存储datablock的记录分配

        Inode文件内容属性发生改变

3,删除文件的过程

        将inode位图中所在的位置为0,block bitmap对应的位也置为0,此时,datablock中的数据不用删除,等再次分配的时候,会覆盖式的写文件,避免了删除的过程。所以删除文件很快。

六,软硬链接

1,软连接

        指令 ln-s 源文件  目标文件,软连接的作用就相当于是windows下的快捷方式,通过快捷方式也可执行文件

2,硬链接

        指令 ln  源文件  目标文件,硬链接的作用就是类似于C++的取别名,其指向相同的地址空间,删除源文件也不会影响硬链接的产生的目标文件

总结

1,语言层的输入输出均封装了系统给的API接口

2,文件描述符就是类似进程,先描述(task_struct),在组织(file_struct),通过file提供的数组下标存文件的指针,然后系统对这个指针管理,只要知道下标,就能在内核中找到信息。

3,重定向就是把本来要输出(输入)通过文件描述符,输出或者输入到我们想让文件去的地方

4,语言有自己的缓冲区,操作系统也有,互不影响

5,inode为文件的索引,其包含文件的属性集合,文件=文件属性(Inode)+文件内容(data Blocks)

6,软连接:快捷方式,硬链接:取别名

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

想找后端开发的小杜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值