linux文件

一切皆文件

Linux的核心思想就是“一切皆文件

Linux 中所有内容都是以文件的形式保存和管理的,即一切皆文件,普通文件是文件,目录(Windows 下称为文件夹)是文件,硬件设备(键盘、监视器、硬盘、打印机)是文件,就连套接字(socket)、网络通信等资源也都是文件。
——引用自C语言中文网

I/O设备也被模型化为文件,对于输入输出的操作就变成了对于文件的读和写,Linux内核提供接口给用户

文件类型

  1. 普通文件:包含任意数据

  2. 目录:包含一组链接的数据
    命令:mkdir创建一个目录
    ls查看目录内容
    rmdir删除目录

  3. 套接字:用来与另一个进程进行跨网络通信的文件

  4. 命名通道

  5. 符号链接

  6. 字符与块设备

硬链接与软连接的区别

在linux中,文件分为两个部分

  1. 文件数据块(记录文件真实内容的地方)
  2. 元数据(记录文件的属性)

其中元数据包含了inode结点,inode结点记录文件的数据区块号码,想要读取文件时,需要通过文件名指向正确的inode号码,通过inode指向文件数据区块,所以inode是文件的唯一标识。
在这里插入图片描述
软链接类似于windows中的快捷方式,软链接有自己的inode结点,结点指向的数据区块里面存储的是另以文件的路径名指向
特点:

  1. 软链接有自己的文件属性和权限
  2. 类似快捷方式,若删除软链接,对原有文件不产生影响
  3. 可以对文件,目录进行链接
  4. 可以跨文件系统
  5. 有自己的inode号
  6. 可以对不存在的文件进行软链接

硬链接则是将不同文件名的文件指向同一个inode结点
特点:

  1. 不可以对目录链接
  2. 只可以对已经存在的文件进行链接
  3. 删除硬链接可能会对文件产生影响(若最后一个指向inode结点的文件被删除,那么文件就会被删除)
  4. 硬链接有相同的inode号
  5. 不可以跨文件系统

在这里插入图片描述
linux的文件系统:
将存储空间分为了三个区块:

  1. 超级区块:记录文件系统的整体信息
  2. inode:记录文件属性
  3. 数据区块:记录文件的实际内容

其中inode与数据区块都有编号,inode占整个文件系统空间的10%,所以当inode空间不足时,也不能创建文件,所以定期清理内存是必要的。

打开文件

调用open函数来创建或者打开一个文件

int open(char *filename, int flags, mode_t mode);
//若成功返回文件描述符,若失败返回-1

每一个进程都有一张文件描述符表,默认打开三个文件

0标准输入(stdin)
1标准输出(stdout)
2标准出错(stderr)

这三个文件描述符被占用了,所以在初始状态下打开文件,描述符从3开始

其中flags为以何种方式打开此文件

O_RDONLY:可读
O_WRONLY:可写
O_RDWR:可读可写
O_CREAT:若文件不存在,就创建一个新的文件
O_TRUNC:如果文件已经存在,则截断
O_APPEND:每次写操作时,设置文件至文件的末尾

mode为访问权限位

掩码描述
S_IRUSR拥有者可以读这个文件
S_IWUSR拥有者可以写这个文件
S_IEUSR拥有者可以执行这个文件
S_IRGRP拥有者所在组的成员可以读这个文件
S_IWGRP拥有者所在组的成员可以写这个文件
S_IEGRP拥有者所在组的成员可以执行这个文件
S_IROTH任何人可以读这个文件
S_IWOTH任何人可以写这个文件
S_IEOTH任何人可以执行这个文件

在使用的时候可以使用这些宏,也可以使用数字,这是一个7进制的数,按照上文表的顺序,每三个宏,决定一个数字
例如:
0111表示S_IEUSR|S_IEGRP|S_IEOTH

关闭文件

使用close函数关闭文件

int close(int fd);
//若成功关闭就返回0,若关闭失败返回-1

读文件

#include<unistd.h>
ssize_t read(int fd,void *buf,size_t n);
//若成功返回读的字节数,若EOF为0,若出错为-1

n为预计读的字节数
返回值的类型是ssize_t(有符号整型)
读文件就是将内容复制到缓冲区

写文件

#include<unistd.h>
ssize_t write(int fd,const void *buf,size_t n);
//若成功返回写的字节数,出错返回-1

const:常量限制符,告诉编译器此变量不可以被修改

以下代码用于将标准输入设备用户敲击的字符输出到标准输入(显示器)上,Read,Write函数封装了对read,write函数出错的解决

int main(void){
	char c;
	while(Read(STDIN_FILENO,1)!=0){
		Write(STDOUT_FILENO,1);
	}
}

共享文件

linux内核用三个数据结构来表示打开的文件
描述符表:每个进程都有,每个打开的米描述符表项都指向文件表中的一个表项
文件表:包括当前的文件位置,引用计数(指向该表项的描述符个数),指向v-node的指针
v-node表:包含stat结构中的大多数信息(stat:文件的元数据)

如果以同一个filename打开文件两次,就会出现以下情况,每个描述符都有自己的文件位置,但是他们指向的文件的内容是一样的
在这里插入图片描述

int main(int argc, char *argv[])
{
    int fd1, fd2;
    char c;
    fd1 = Open(fname, O_RDONLY, 0);
    fd2 = Open(fname, O_RDONLY, 0);
    Read(fd1, &c, 1);
    Read(fd2, &c, 1);
    printf("c = %c\n", c);

    Close(fd1);
    Close(fd2);
    return 0;
}

由于fd1与fd2指向的是两个不同的文件表项,但文件表项指向的v-node是同一个,所以两次read的结果是一样的,都是文件的第一个字符

I/O重定向

I重定向:输入到终端改变为输入到文件
O重定向:输出到终端变为输出到文件

其中一种重定向的方式就是使用dup2函数

int dup2(int oldfd,int newfd);

重定向的实质就是将文件描述符指向另一个文件

dup2(fd4,fd1);

如下图:
在这里插入图片描述
由于两个描述符指向的是同一个文件表项昂,所以对fd1操作,相当于对fd4操作

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值