学习日志之系统级I/O

在Linux系统中一切皆文件。

●打开文件。一个应用程序通过要求内核打开相应的文件,来宣告它想要访向一个I/O设备。内核返回一个小的非负整数,叫做描述符,它在后续对此文件的所有操作中标识这个文件。内核记录有关这个打开文件的所有信息。应用程序只需记住这个描述符。
●Linux shell创建的每个进程开始时都有三个打开的文件:标准输入(描述符为0), 标准输出(描述符为1)和标准错误(描述符为2)。头文件< unistd.h> 定义了常量STDEN_FILENO、STDOUT_ FILENO和STDERR_FILENO, 它们可用来代替显式的描述符值。
●改变当前的文件位置。对于每个打开的文件,内核保持着一个文件位置k,初始为0。这个文件位置是从文件开头起始的字节偏移量。应用程序能够通过执行seek操作,显式地设置文件的当前位置为k。
●读写文件。一个读操但就是从文件复制n>0个字节到内存,从当前文件位置k开始,然后将k增加到k+n。给定一个大小为m字节的文件,当k≥m时执行读操作会触发一个称为end-of-file( EOF)的条件,应用程序能检测到这个条件。在文件结尾处并没有明确的“EOF 符号”。
类似地,写操作就是从内存复制力n >0个字节到一个文件从当前文件位置点开始,然后更新k。
●关闭文件。当应用完成了对文件的访问之后,它就通知内核关闭这个文件。作为响应内核释放文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池中。无论一个进程因为何种原因终止时,内核都会关闭所有打开的文件并释放它们的内存资源。

1.打开和关闭文件
open():用来打开一个已存在的文件或者创建一个新文件。

#include <sys/types.h>
#include <sys/stat.h>
#include < fcntl.h>
int open(char *filename,int flags, mode_t mode);
返回:若成功则为新文件描述符,若出错则为-1。

flags参数指明了进程打算如何访问这个文件:
●O_ RDONLY:只读。
●O_ WRONLY:只写。
●O_ RDWR:可读可写。
flags参数也可以是一个或者更多位掩码的或,为写提供给一些额外的指示:
●O_CREAT:如果文件不存在,就创建它的一个截断的(truncated)(空)文件。
●O_ TRUNC:如果文件已经存在,就截断它。
●O_APPEND: 在每次写操作前,设置文件位置到文件的结尾处。

mode指定了新文件的访问权限位,这里不做详细说明。
close():关闭一个打开的文件。

#include <unistd.h>
int close(int fd);
返回:若成功则为0,若出错则为-1。

2.读和写文件

#include <unistd.h>
ssize_ t read(int fd, void *buf, size_t n) ;
返回:若成功则为读的字节数,若EOF则为0,若出错为-1。
ssize_ t write(int fd,const void *buf, size_t n);
返回:若成功则为写的字节数,若出错则为-1。

read函数从描述符为fd的当前文件位置复制最多n个字节到内存位置buf。返问值-1表示一个错误,而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。
write 函数从内存位置buf复制至多n个字节到描述符fd的当前文件位置。

example

/* $begin cpstdin */
#include "csapp.h"

int main(void) 
{
   
    char c;

    while(Read(STDIN_FILENO, &c, 1) != 0) 
	Write(STDOUT_FILENO, &c, 1);
    exit(0);
}

操作及运行结果:任意在键盘上几个字符后按下回车,下面会显示相同的字符串。在这里插入图片描述
分析:
程序使用read和write调用一次一个字节地从标准输入复制到标准输出。Read(STDIN_FILENO, &c, 1)相当于getchar(),从键盘上接收一个字符。

3.I/O重定向

#include <unistd.h>
int dup(int fd);
int dup2(int oldfd, int newfd);
返回:若成功则为非负的描述符,若出错则为- 1。

两个均为复制一个现存的文件的描述

由dup返回的新文件描述符一定是当前可用文件描述中的最小数值。

dup2函数复制描述符表表项oldfd到描述符表表项newfd,覆盖描述符表表项newfd以前的内容。如果newfd已经打开了,dup2会在复制oldfd之前关闭newfd.
假设在调用dup2(4,1)之前,我们的状态如图1 所示,其中描述符1(标准输出)对应于文件A(比如一个终端),描述符4对应于文件B(比如一个磁盘文件)。A和B的引用计数都等于1。图2显示了调用dup2(4,1)之后的情况。两个描述符现在都指向文件B;文件A已经被关闭了,并且它的文件表和v-node表表项也已经被删除了;文件B 的引用计数已经增加了。从此以后,任何写到标准输出的数据都被重定向到文件B。
在这里插入图片描述
------------------------------------------------------------- 图1----------------------------------------------------------------------------------
在这里插入图片描述
---------------------------------------------------------------图2-------------------------------------------------------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值