文件描述符

UNIX系统 ---- 文件I/O

大憨熊 提交于 2020-02-07 02:45:31
一、文件描述符 对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write。 二、open函数 调用open函数可以打开或创建一个文件。 int open ( const char * pathname , int oflag , . . . , /*mode_t mode8/ ); pathname是要打开或创建的文件的名字。 oflag参数可用来说明此函数的多个选择项。 O_RDONLY 只读打开。 O_WRONLY 只写打开。 O_RDWR 读、写打开。 O_APPEND 每次写时都加到文件的尾端。 O_CREAT 若此文件不存在则创建它。 O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则出错。 O_TRUNC 如果此文件存在,而且为只读或只写成功打开,则将其长度截短为 0。 O_NOCTTY 如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。 O_NONBLOCK 如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式。 O_SYNC 使每次write都等到物理I

【Linux】系统文件IO

你。 提交于 2020-02-06 20:23:28
系统文件IO 系统调用接口 open write read lseek close 文件描述符fd 文件描述符的分配规则:最小未使用 重定向 系统调用接口 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: 追加写 O_TRUNC:打开同时截断文件为0长度 mode:文件创建权限(最后文件的权限是mode &~ umask) 可以通过mode_t umask(mode_t mask);函数将当前进程的文件创建权限掩码修改为mask 返回值: 成功

文件io和标准io的联系

核能气质少年 提交于 2020-02-06 06:13:47
 linix对IO文件的操作分为不带缓存的IO操作(文件IO都是不带缓存IO)和带缓存的标准IO操作.   刚开始,要明确以下几点:    不带缓存,其实不是直接对磁盘文件进行读取操作 ,像read()和write()函数,它们都属于系统调用,只不过在用户层没有缓存,所以叫做无缓存IO,但对于内核来说,还是进行了缓存,只是用户层看不到罢了。 1.  linux的文件I/O是一种低级的I/O,由操作系统提供的基本IO服务。(底层)    而标准I/O是ANSIC建立的一种标准I/O模型,是一种标准函数包和stdio.h头文件中的定义,具有一定的可移植性。(标准库封装) 2.   标准I/O默认采用了缓冲机制,还创建了一个包含文件和缓冲区相关数据的数据结构。       文件I/O一般没有采用缓冲模式,需要自己创建缓冲区。 3.  所有I/O函数都是针对文件描述符的。当打开一个文件时,即返回一个文件描述符,然后该文件描述符就用于后续的I/O操作。    而对于标准I/O库,它们的操作则是围绕流进行的。当用标准I/O库打开或创建一个文件时,我们已使用一个流与一个文件相关联。 4.   标准的 C 库函数(标准io)建立在底层系统调用(文件io)之上 ,即 C 函数库文件访问函数的实现中使用了文件 I/O 系统调用。    标准的 C 库中的文件处理函数为了减少使用系统调用的次数,提高效率

为什么要使用epoll

馋奶兔 提交于 2020-02-06 04:11:52
为什么要使用epoll select不足 1.select需要从用户态将监听的集合拷贝给内核, 2.内核通过轮询的方式查找有事件的文件描述符并返回 3.且文件描述符有上限 4.没有直接告诉我们具体哪个fd有数据,导致需要遍历 Epoll函数就是解决select的不足的 从第一个函数看起int epoll_create(int size); 创建epoll函数 返回一个epoll对象 这个epoll对象其实也是个文件描述符,但是这个文件描述符的本质其实是一个二叉树,平衡二叉树,也就是红黑树左子树和右子树高度差小于1.这个函数调用成功将在内核中发生。 第二个函数int epoll_ctl(int epfd, int op, int fd, struct epoll_event event); 第一个参数epfd是那个红黑树文件描述符不必说了 第二个参数Int op代表的是对这个对象的各种操作增删改查 第三个参数指的是需要监听的套接字。 第四个参数则是结构体的指针 struct epoll_event { uint32_t events; / Epoll 事件 / 就是监听套接字的各种事件 读写连接等等 epoll_data_t data; / 用户数据 */ IP端口等等 }; 等待返回函数int epoll_wait(int epid, struct epoll_event

异步I/O和非阻塞I/O(轮询)

有些话、适合烂在心里 提交于 2020-02-05 13:50:31
异步与非阻塞听起来似乎是一回事。从实际效果而言,两者都达到了我们并行I/O的目的。但从计算机内核I/O而言,异步/同步和阻塞/非阻塞实际上是两回事。 操作系统内核对于 I/O只有两种方式 :阻塞与非阻塞。 在调用 阻塞I/O 时,应用程序需要等待I/O完成才返回结果。阻塞I/O的一个特点是调用之后一定要等到系统内核层面完成所有操作后,调用才结束。以读取磁盘上的一段文件为例,系统内核在完成磁盘寻道、读取数据、复制数据到内存中之后,这个调用才结束。阻塞I/O造成CPU等待I/O,CPU的处理能力不能得到充分利用。为了提高性能,内核提供了非阻塞I/O。 非阻塞I/O 调用之后会立即返回。返回之后,CPU的时间片可以用来处理其他事务,此时的性能提升是明显的。 但非阻塞I/O也存在一些问题,用于完整的I/O并没有完成,立即返回的并不是业务层期望的数据,而仅仅是当前调用的状态。为了获取完整的数据,应用程序需要重复调用I/O操作来确认是否完成。这种重复调用判断操作是否完成的技术叫做 轮询 。 任意技术都并非完美的。阻塞I/O造成CPU等待,非阻塞I/O带来的麻烦却是需要轮询去确认是否完全完成数据获取,它会让CPU处理状态判断,这是对CPU资源的浪费。 下面完美看看轮询技术是如何演进以减小I/O状态判断的CPU损耗。 现存的轮询技术主要有一下几种: 1. read: 最原始性能最低的一种

阻塞I/O、非阻塞I/O和I/O多路复用

£可爱£侵袭症+ 提交于 2020-02-05 13:23:00
一、阻塞I/O 首先,要从你常用的IO操作谈起,比如read和write,通常IO操作都是阻塞I/O的,也就是说当你调用read时,如果没有数据收到,那么线程或者进程就会被挂起,直到收到数据。阻塞的意思,就是一直等着。阻塞I/O就是等着数据过来,进行读写操作。应用的函数进行调用,但是内核一直没有返回,就一直等着。应用的函数长时间处于等待结果的状态,我们就称为阻塞I/O。每个应用都得等着,每个应用都在等着,浪费啊!很像现实中的情况。大家都不干活,等着数据过来,过来工作一下,没有的话继续等着。 二、非阻塞I/O 非阻塞IO很简单,通过fcntl(POSIX)或ioctl(Unix)设为非阻塞模式,这时,当你调用read时,如果有数据收到,就返回数据,如果没有数据收到,就立刻返回一个错误,如EWOULDBLOCK。这样是不会阻塞线程了,但是你还是要不断的轮询来读取或写入。相当于你去查看有没有数据,告诉你没有,过一会再来吧!应用过一会再来问,有没有数据?没有数据,会有一个返回。但是依旧很不好。应用必须得过一会来一下,问问内核有木有数据啊。这和现实很像啊!好多情况都得去某些地方问问好了没有?木有,明天再过来。明天,好了木有?木有,后天再过来。。。。。忙碌的应用。。。。 三、I/O多路复用 多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态

复制文件描述符,dup函数详细说明及用法,dup2函数详细说明及用法(文件IO)【linux】(k)

只谈情不闲聊 提交于 2020-02-04 02:20:45
dup函数详细说明及用法,dup2函数详细说明及用法 dup函数 功能 返回值 参数 dup2函数 函数原型 功能 返回值 参数 dup函数 函数原型 include <unistd.h> int dup(int oldfd); 功能 复制某个已经打开的文件描述符,得到一个新的描述符,这个新的描述符,也指向被复制描述符所指向的文件。 比如:4指向了某个文件,从4复制出5,让5也指向4指向的文件。 至于需要用到的新描述符,dup会使用描述符池(0~1023)中当前最小没用的那一个。 返回值 成功:返回复制后的新文件描述符 失败:返回-1,并且errno被设置。 参数 oldfd:会被复制的、已经存在的文件描述符。 代码演示 我们先来看以下这两个文件描述符的值。 代码为: 执行结果为: 那么我们看到新的文件描述符为3和4, 因为当文件打开的时候012已经被使用,open的时候文件描述符池中最小的没有被使用是3,dup复制出新的文件描述符继续使用文件描述符中最小的没有被使用的4。 由于是赋值所以两个文件描述符指向同一个文件: 那么接下来我们查看使用这两个文件描述符能不能向同一个文件写入数据: 执行结果为: 我们可以看到写入成功了。 dup2函数 函数原型 #include <unistd.h> int dup2(int oldfd, int newfd); 功能 功能同dup

管道符、重定向与环境变量

独自空忆成欢 提交于 2020-02-03 01:50:20
主要内容: 1、定向技术的5种模式 2、管道命令符 3、Linux系统命令中常见的通配符和转义符 输入输出重定向 输入重定向是将文件导入到命令中 输出重定向是将输出到屏幕的结果导入文件中(分类:标准输出重定向 || 错误输出重定向) 标准输入重定向(STDIN,文件描述符为0):默认从键盘输入,也可以从其他文件或命令中输入 标准输出重定向(STDOUT,文件描述符为1):默认输出到屏幕 错误输出重定向(STDREE,文件描述符为2):默认输出到屏幕 输入重定向中用到的符号及作用 符号 作用 命令 < 文件 将文件作为命令的标准读入 命令 << 分界符 从标准输出中读入,知道遇见分界符停止 命令 < 文件1 > 文件2 将文件1作为命令的标准输入并将标准输出到文件2 输出重定向中用到的符号将其作用 符号 作用 命令 > 文件 将标准输出重定向到一个文件中(清空原有文件的数据) 命令 2> 文件 将错误输出重定向到一个文件中(清空原有文件的数据) 命令 >> 文件 将标准输出重定向到一个文件中(追加到原有内容的后面) 命令 2 >> 文件 将错误输出重定向到一个文件中(追加到原有内容的后面) 命令 >> 文件 2 >&1 或 命令 &>> 文件 将标准输出与错误输出共同写入到文件中(追加到原有内容的后面) 注:对于输出重定向的标准输出模式。可省略文件描述符1不写

2.1&2.2python学习笔记

守給你的承諾、 提交于 2020-02-02 21:10:22
1) 函数参数 1. 必选参数在前,默认参数在后 ( 多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数 ) 2. 可变参数:参数前面加了一个 * 号(在 list 或 tuple 前面加一个 * 号,把 list 或 tuple 的元素变成可变参数传进去); 3. 关键字参数 : 参数前面加了个 ** , (在 dict 的前加 ** , dict 中所有 key-value 用关键字参数传入到函数的 ** 变量中, ** 变量将获得一个 dict ,注意变量获得的 dict 是一份拷贝,对变量的改动不会影响到函数外的 dict )。 如果要限制关键字参数的名字,就可以用命名关键字参数: def person(name, age, *, city, job):#(只接收city和job作为关键字参数) 命名关键字参数需要一个特殊分隔符 * , * 后面的参数被视为命名关键字参数 作用:限制要传入的参数的名字,只能传我已命名关键字参数。 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符 * 了: def person(name, age, *args, city, job): ps: 定义默认参数要牢记一点:默认参数必须指向不变对象! 2 )列表生成器 示例:L1 = ['Hello', 'World', 18,

exec 1>&0

青春壹個敷衍的年華 提交于 2020-02-02 13:31:46
最近在做hgame2020-pwn的一道题 findyourself 中,官方wp给出了一条linux命令是 exec 1>&0 ,不解其意,直接查找也找不到这条命令到底是干什么的,拐弯抹角地先了解了文件描述符,然后才了解了这条命令。 程序的原意是输入一个字符串s1,经过字符检查后执行如下三条语句: close(1);close(2);system(&s1); 我们的目的是要得到shell,官方wp给的是此处可以输入串: $0 然后可以执行新的命令 exec 1>&0 以及其他以查看到flag 那么这条语句是什么意思呢?其中的0和1是指什么呢? 0和1是linux下的 文件描述符 。 在Linux中一切皆文件,文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的 索引 ,是一个 非负整数 (通常是小整数), 用于指代被打开的文件 ,所有执行I/O操作的系统调用都通过文件描述符。程序刚刚启动的时候, 0是标准输入,1是标准输出,2是标准错误 。如果此时去打开一个新的文件,它的文件描述符会是3。 标准输入输出的指向是默认的,我们可以修改它们的指向,也即 重定位 举例子,可以用 exec 1>myoutput 把标准输出重定向到myoutput文件中,也可以用 exec 0<myinput 把标准输入重定向到myinput文件中,而且,文件名字可以用&