深入理解计算机系统-第十章 系统级I/O

链接
系统级I/O
相关函数
运行结果

Unix I/O

输入/输出(I/O)是在主存和外部设备之间复制数据的过程。输入操作是从I/O设备复制数据到主存,输出操作是从主存复制数据到I/O设备。
一切皆文件。所有的I/O设备都被模型化为文件,所有的输入输出都被当作对相应文件的读和写来执行。
文件描述符(file descriptor):内核返回一个小的非负整数叫做描述符。内核利用它来标识文件。
Linux shell创建的每个进程开始时都有三个打开的文件:标准输入(描述符为0),标准输出(描述符为1),标准错误(描述符为2)。
关闭文件后,内核会释放数据结构,并将该文件的描述符恢复到可用的描述符池中。

文件

每个Linux文件都有一个类型来表明它在系统中的角色:

  • 普通文件(regular file):包含任意数据。包括文本文件和二进制文件。

  • 目录(directory):是包含一组链接的文件,每个链接都将一个文件名映射到一个文件。
    · 链接(link):链接是对文件的引用。在 Linux 中,链接可以如同原始文件一样来对待。链接可以与普通的文件一样被执行、编辑和访问。对系统中的其他应用程序而言,链接就是它所对应的原始文件。链接不是副本,当通过链接对文件进行编辑时,编辑的实际上是原始文件。有两种类型的链接:硬链接和软链接(符号链接)。
    硬链接:用 ln [源文件] [目标文件] 命令可以生成一个硬链接。
    硬链接只能引用同一文件系统中的文件,不能对目录文件进行创建硬链接操作。硬链接文件不能跨文件系统。
    硬链接文件不占用存储空间,它引用的是文件在文件系统中的物理索引(inode)。
    修改源文件或者目标文件, 对应另外一个文件也会发生相应修改。
    当移动或删除原始文件时,硬链接不会被破坏,因为它所引用的是文件的物理数据而不是文件在文件结构中的位置。
    硬链接的文件不需要用户有访问原始文件的权限,也不会显示原始文件的位置,这样有助于文件的安全。
    软连接:用 ln -s 命令可以生成一个软连接。
    软链接文件只是其源文件的一个标记,当删除了源文件后,链接文件不能独立存在,虽然仍保留文件名,但却不能查看软链接文件的内容了。
    链接文件甚至可以链接不存在的文件,这就产生一般称之为”断链”的现象,链接文件甚至可以循环链接自己。类似于编程语言中的递归。
    在对符号文件进行读或写操作的时候,系统会自动把该操作转换为对源文件的操作,但删除链接文件时,系统仅仅删除链接文件,而不删除源文件本身。

  • 套接字(socket):是用来与另一个进程进行跨网络通信的文件。

可以用mkdir命令创建一个目录,用ls查看其内容,用rmdir删除该目录。
下图用mkdir命令创建了一个名为direc的目录,又用rmdir删除了该目录
在这里插入图片描述
ls -l 命令可查看当前目录下所有可见文件的详细属性。
在这里插入图片描述

以all目录为例:
文件属性: 第①个字符:-表示普通文件,d表示目录文件; -代表无权限,r代表具有可读权限,w代表具有可写权限,x代表具有可执行权限
drwxr-xr-x,第①个字符d表示该文件是一个目录。rwx表示(拥有者)属主权限,可读、可写、可执行权限。r-x表示(拥有者所在组的成员)组权限,可读、可执行。r-x表示其他用户权限,可读、可执行。
文件硬链接数量:31
所有者:tangein
所属用户组:tangein
文件大小:4096 byte
修改时间:2019年1月22日
文件名:all

chmod命令可改变文件属性。+ 表示增加权限,- 表示取消权限,= 表示唯一设定权限。

打开和关闭文件

open函数

  • 头文件
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

  • 定义函数
    int open(char *filename, int flags);
    int open(char *filename, int flags, mode_t mode);

  • 参数说明
    pathname 指向欲打开的文件路径字符串
    flags 指明进程如何访问文件:
    · O_RDONLY 只读
    · O_WRONLY 只写
    · O_RDWR 可读可写

    · O_CREAT 如果文件不存在就创建它的一个截断的(空)文件。
    · O_TRUNC 如果文件存在,就截断它。即如果文件存在且为普通文件,打开方式为可写(O_WRONLY或O_RDWR),则清空文件内容。
    · O_APPEND 在每次写操作前,设置文件位置到文件的结尾处

  • 返回值
    若成功则为新文件描述符,若出错则为-1

  • 函数功能
    打开一个已存在的文件或创建一个新文件

close函数

  • 头文件
    #include <unistd.h>

  • 定义函数
    int close(int fd);

  • 参数说明
    fd 是要关闭的文件描述符

  • 返回值
    若成功则为0,若出错则为1

  • 函数功能
    关闭一个打开的文件 (关闭一个已关闭的描述符会出错)

#include "csapp.h"
int main()
{
 int fd1,fd2;
 fd1=Open("foo.txt",O_RDONLY,0);
 Close(fd1);
 fd2=Open("baz.txt",O_RDONLY,0);
 printf("fd2=%d\n",fd2);
 exit(0);
}

该程序的输出结果为 fd2=3
open函数总是返回最低的未打开的描述符。第一次调用open返回3,即fd1=3,调用close函数释放描述符3。因此再次调用open返回3,即fd2=3。

读和写文件

read函数

  • 头文件
    #include <unistd.h>

  • 定义函数
    ssize_t read(int fd, void *buf, size_t n);

  • 参数说明
    fd 是要读的文件描述符
    buf 是要读入的内存位置
    n 表示最多读入的字节数

  • 返回值
    若成功则为读的字节数,若EOF则为0,若出错则为-1

  • 函数功能
    从文件中读

write函数

  • 头文件
    #include <unistd.h>

  • 定义函数
    ssize_t write(int fd, const void *buf, size_t n);

  • 参数说明
    fd 是要写的文件描述符
    buf 指向一段要写入的内存空间的首地址
    n 表示最多写入的字节数

  • 返回值
    若成功则为写的字节数,若出错则为-1

  • 函数功能
    写到一文件中

读取文件元数据

stat和fstat函数

  • 头文件
    #include <unistd.h>
    #include <sys/stat.h>

  • 定义函数
    int stat(const char *filename, struct stat *buf);
    int fstat(int fd, struct stat *buf);

  • 参数说明
    stat函数以一个文件名filename作为输入,fstat函数以一个文件描述符fd作为输入,填写stat数据结构中的各个成员
    struct stat{
    dev_t st_dev;
    ino_t st_ino;
    mode_t st_mode; /* 文件访问许可位和文件类型 * /
    nlink_t st_nlink;
    uid_t st_uid;
    gid_t st_gid;
    dev_t st_rdev;
    off_t st_size; /* 文件的字节数大小* /
    timestruc_t st_atim;
    timestruc_t st_mtim;
    timestruc_t st_ctim;
    blksize_t st_blksize;
    blkcnt_t st_blocks;
    char st_fstype[_ST_FSTYPSZ];
    };

  • 返回值
    若成功则为0,若出错则为-1

  • 函数功能
    检索关于文件的信息。

I/O重定向

dup函数和dup2函数

  • 头文件
    #include <unistd.h>

  • 定义函数
    int dup(int fd);
    int dup2(int oldfd, int newfd);

  • 参数说明
    fd 是一个文件描述符
    oldfd 是重定向后的文件描述符
    newfd 是被覆盖的文件描述符

  • 返回值
    若成功则为非负的描述符,若出错则为-1

  • 函数功能
    复制一个现存的文件描述符;
    复制描述符表表项oldfd到描述符表表项newfd,并覆盖newfd的内容

假设:描述符1对应文件A,描述符4对应文件B。A、B的引用计数都等于1
在这里插入图片描述

调用dup2(4,1)后,两个描述符都指向文件B。
此时文件A被关闭,并且A的文件表和v-node表表项都已经被删除了
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值