linux文件io/系统调用io中的open(),close(),read(),write(),lseek()函数

linux文件io/系统调用io中的open(),close(),read(),write()函数

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


文件描述符的概念

我们知道在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件、目录文件、链接文件和设备文件。在操作这些所谓的文件的时候,我们每操作一次就找一次名字,这会耗费大量的时间和效率。所以Linux中规定每一个文件对应一个索引,这样要操作文件的时候,我们直接找到索引就可以对其进行操作了。

文件描述符(filedescriptor)就是内核为了高效管理这些已经被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符来实现。同时还规定系统刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。这意味着如果此时去打开一个新的文件,它的文件描述符会是3,再打开一个文件文件描述符就是4…

Linux内核对所有打开的文件有一个文件描述符表格,里面存储了每个文件描述符作为索引与一个打开文件相对应的关系,简单理解就是下图这样一个数组,文件描述符(索引)就是文件描述符表这个数组的下标,数组的内容就是指向一个个打开的文件的指针。

————————————————版权声明:本文为CSDN博主「杰克小麻雀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/yushuaigee/article/details/107883964


关于文件描述符更详细的解释的文章

一 、open()函数

功能:打开文件。

头文件:
#includ e <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);

返回值:打开成功:返回一个int 型正整数(文件描述符);打开失败:返回 -1; 参数说明:pathname 指向文件路径的字符指针;
flags 文件打开方式 常用选项是:O_RDONLY(只读);O_WRONLY(只写); O_RDWR(可读写);
O_CREAT:文件不存在时,创建该文件, 文件的权限由第三个参数mode决定最终的权限。 mode
当flags选项是O_CREAT时,需要使用mode指定文件权限。 mode: 创建的文件的权限,一般0664
指定文件拥有者,群组用户及其他用户都拥有对文件的读写执行权限。其他相关权限可查阅

flags: 打开方式详细说明

  O_RDONLY:  只读打开

   O_WRONLY:  只写打开

   O_RDWR: 可读写打开

   O_CREAT: 当文件不存在时创建文件,此时需要第三个参数mode
  			 mode: 创建的文件的权限,一般0664
   O_TRUNC: 当文件存在时清空文件内容

    O_APPEND: 追加打开

二、close()函数

close函数功能:关闭一个已打开的文件。

#includ e <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int close(int fd);

返回值:成功返回0,出错返回-1并设置errno
参数fd是要关闭文件描述符。当一个进程终止时,内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close,在终止时内核也会自动关闭它打开的所有文件。
由open返回的文件描述符一定是该进程尚未使用的最小的描述符。

三、 read()函数

read()函数功能:用来读取打开文件的数据

read()函数
头文件和函数原型
#include <unistd.h>
 ssize_t read(int fd, void *buf, size_t count);
// ssize_t 是有符号整数类型;size_t是无符号整数类型

参数

fd: 文件描述符(文件名或文件路径)

buf: 存放输入数据的内存缓冲区地址

count: 指定最多能读取的字节数

返回值

读取成功:返回的是读取到的字节数

读取到文件尾:0

读取失败:-1

1.如果读取成功,则返回实际读到的字节数。这里又有两种情况:一是如果在读完count要求字节之前已经到达文件的末尾,那么实际返回的字节数将小于count值,但是仍然大于0;二是在读完count要求字节之前,仍然没有到达文件的末尾,这是实际返回的字节数等于要求的count值。
2、如果读取时已经到达文件的末尾,则返回0。
3、如果出错,则返回-1。

注意:

比如一个有100个字节的文件,第一次读取10个字节,这时读取指针在第10个字节处。再次进行10个字节的读操作时,会接着第一次读的位置接着往后读。如果还想从开始读,可使用lseek函数定位。


四、write()函数

write()函数功能:将数据写入一个已打开的文件中。

write()函数
头文件与函数原型
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

参数

与read()函数类似

fd: 文件描述符(文件名或文件路径)

buf: 要写入文件中数据的内存地址

count: 从 buf 写入文件的数据字节数

返回值

写入成功: 返回 实际写入的字节数

写入失败:-1

五、lseek()函数

对于每个打开的文件,系统都会记录它的读写位置偏移量,我们也把这个读写位置偏移量称为读写偏移量,Linux 中可使用系统函数 lseek 来修改文件偏移量 ( 读写位置 )
函数代码

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

参数

fd: 文件描述符。
offset: 偏移量,以字节为单位。
whence: 用于定义参数 offset 偏移量对应的参考值,该参数为下列其中一种(宏定义):
SEEK_SET:读写偏移量将指向 offset 字节位置处(从文件头部开始算);
SEEK_CUR:读写偏移量将指向当前位置偏移量 + offset 字节位置处, offset 可以为正、也可以为负,如果是正数表示往后偏移,如果是负数则表示往前偏移;
SEEK_END:读写偏移量将指向文件末尾 + offset 字节位置处,同样 offset 可以为正、也可以为负,如果是正数表示往后偏移、如果是负数则表示往前偏移。
返回值:成功将返回从文件头部开始算起的位置偏移量(字节为单位),也就是当前的读写位置;发生错误将返回-1,并设置errno值。

程序演示

程序实现:文件内容copy

  1 #include <stdio.h>
  2 #include<stdlib.h>
  3 #include <sys/types.h>
  4 #include <sys/stat.h>
  5 #include <fcntl.h>
  6 #include <unistd.h>
  7 int main(int varg,char **vary)
  8 {
  9   char buffer[1024];//定义一个数组来存储读取到的数据
 10   if(varg < 3)
 11   {                                                                                   
 12     fprintf(stderr,"输入的参数不够,请输入三个参数");    
 13   }                                    
 14   int ps,pr,n;    
 15   ps= open(vary[1],O_RDONLY);//已只读的形式打开第一个文件,将打开的文件描述符赋值给ps
 16   /*打开第二个文件 如果没有则创建文件创建文件的执行权限(八进制:0644)为-rw-r-r,打开文件之后将文件内容清空 */
 17   umask(0000);              
 18   pr= open(vary[2],O_WRONLY|O_CREAT,O_TRUNC,0644);                                                                                  
 19   while((n=read(ps,buffer,1024))>0)//一次从文件中读取1024个字节并存储到buffer中,n大于0则说明文件内容还未读取完
 20   {
 21     write(pr,buffer,n);                                            
 22   }                                                              
 23   close(ps);                                              
 24   close(pr);//关闭打开的两个文件      
 25 }                                                          
~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嵌入式学习~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值