都需要包含头文件: <unistd.h>

read系统函数从打开的设备或文件中读取数据,即将数据从外设上经过内核读到用户空间;write系统函数相反,向打开的设备或文件中写入数据,即将数据从用户空间(I/O缓冲)送到内核,然后刷到外设上。它们的函数原型如下:

ssize_t read(int fd, void *buf, size_t count);   

ssize_t为有符号整型,size_t为无符号整型。fd为相应的文件描述符;buf为用户给定的数据缓冲区,该缓冲不是固定大小的,由count值决定其大小(用户给定,字节数)。如 read( fd , “hello” , 5 ); 此时的void *buf为char *类型。即count为请求读取的字节数(即buf的大小)。该函数的返回值为-1时,表示读取数据失败;返回值>0时,表示读出的字节数;返回值等于0时,表示已经读完了,因此没有数据可读了。

ssize_t write(int fd, const void *buf, size_t count);

buf为需要输出的缓冲区,由用户给定。cout为最大输出字节数(buf的大小,字节数)。返回值为-1时,表示写入失败;>=0时,表示写入的字节数。

以上两个缓冲区buf都是用户空间的地址,但是与I/O缓冲区不一样,后者是规定的,前者是用户自己指定的。

思考:利用readwrite每次读或写1Byte与利用getsputs每次读或写1Byte哪一种方式速度更快?

read和write函数为Linux系统函数,其缓冲区由用户来维护,即用户指定其大小,从而每次要将用户空间的数据送到内核或从内核送到用户空间的数据大小是由用户来规定的(count);而gets和puts为C库函数,其I/O缓冲区由库函数自己维护,大小为8Byte,因此平均上,每传送8个Byte的数据量才会操作一次内核。综上,以上两者在读写数据时,显然read、write函数每次从用户空间读1Byte数据是就会操作一次内核(系统调用)(,开销更大,速度会更慢。而puts和gets函数速度更快。 当然,用户可以指定read和write的count参数,来增大其缓冲区大小,从而提高其读写速度,使其比puts和gets更快(对大文件来说,效果更加明显)。

下面举例说明read和write的用法:

//将一个文件(english.txt)的内容读到另一个文件(writefile.txt

[root@localhost work]# vim rdwr.c

[root@localhost work]# ls

english.txt  rdwr.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>int main( )
{int fd;fd = open("english.txt",O_RDONLY);  //以只读方式打开printf("open readfile's fd=%d\n",fd);if( fd == -1 ){perror(" open english.txt " );exit(1);}int fd1;char buff[1024] = { 0 };    //定义一个缓冲区fd1 = read( fd,buff,sizeof(buff) );   //将数据读出到缓冲区printf("read readfile's fd1=%d\n",fd1);if( fd1 == -1 ){perror(" read english.txt " );exit(1);}int fd2;fd2 = open( "writefile.txt" ,O_WRONLY | O_CREAT | O_EXCL,0664);  //创建一个写文件,并以只写的方式打开,如果文件创建的文件存在,则结束printf("open writefile's fd2=%d\n",fd2);if ( fd2 == -1 ){perror( "creat file" );exit(1);}int ret;while( fd1 ){ret = write( fd2,buff,fd1);  //将读出的数据写进另一个新文件if( ret == -1 ){perror( "write file");exit(1);}fd1 = read( fd,buff,1024);  //再次读数据到缓冲区if( fd1 == -1 ){perror(" read english.txt " );exit(1);}}int qw1;int qw2;qw1=close(fd);  //关闭文件if( ret == -1 ){perror( "close readfile");exit(1);}qw2=close(fd2);if( ret == -1 ){perror( "close writefile");exit(1);}return 0;
}

[root@localhost work]# gcc -pipe -pedantic -Wall -ggdb3 rdwr.c -o rdwr

[root@localhost work]# ./rdwr

open readfile's fd=3

read readfile's fd1=1024

open writefile's fd2=4

[root@localhost work]# ls

english.txt  rdwr  rdwr.c  writefile.txt

[root@localhost work]# ll writefile.txt

-rwxrwxrwx. 1 root root 109055 Mar 19 11:39 writefile.txt

[root@localhost work]# ll english.txt

-rwxrwxrwx. 1 root root 109055 Mar 19 10:30 english.txt  //两文件大小一样

read和write函数的使用相关推荐

  1. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  2. Mysql函数group_concat、find_in_set 多值分隔字符字段进行数据库字段值翻译

    Mysql函数group_concat.find_in_set进行数据库字段值翻译 场景 配方表:记录包含的原料 sources表示原料,字段值之间用逗号分隔 原料表:对应原料id和原料名称 现需要查 ...

  3. C++ 笔记(34)— C++ exit 函数

    当遇到 main 函数中的 return 语句时,C++ 程序将停止执行.但其他函数结束时,程序并不会停止.程序的控制将返回到函数调用之后的位置.然而,有时候会出现一些非常少见的情况,使得程序有必要在 ...

  4. C++ 笔记(30)— 友元函数与友元类

    我们知道类的私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行.这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦. ...

  5. 浅显易懂 Makefile 入门 (07)— 其它函数(foreach 、if、call、origin )

    1. foreach 函数 foreach 函数定义如下: $(foreach <var>,<list>,<text>) 函数的功能是:把参数 <list&g ...

  6. 浅显易懂 Makefile 入门 (06)— 文件名操作函数(dir、notdir、suffix、basename、addsuffix、addperfix、join、wildcard)

    编写 Makefile 的时候,很多情况下需要对文件名进行操作.例如获取文件的路径,去除文件的路径,取出文件前缀或后缀等等. 注意:下面的每个函数的参数字符串都会被当作或是一个系列的文件名来看待. 1 ...

  7. Go 学习笔记(65)— Go 中函数参数是传值还是传引用

    Go 语言中,函数参数传递采用是值传递的方式.所谓"值传递",就是将实际参数在内存中的表示逐位拷贝到形式参数中.对于像整型.数组.结构体这类类型,它们的内存表示就是它们自身的数据内 ...

  8. Go 学习笔记(61)— Go 高阶函数、函数作为一等公民(函数作为输入参数、返回值、变量)的写法

    函数在 Go 语言中属于"一等公民(First-Class Citizen)"拥有"一等公民"待遇的语法元素可以如下使用 可以存储在变量中: 可以作为参数传递给 ...

  9. C++ 笔记(26)— 主函数 main(int argc, char *argv[]) 参数说明

    带形参的 main 函数,如 int main( int argc, char* argv[], char **env ) 是 UNIX .Linux 以及 Mac OS 操作系统中 C/C++ 的 ...

  10. OpenCV 笔记(09)— 常用的数据结构和函数(Vec、Point、Scalar、Size、Rect、cvtColor)

    1. Vec 对象类型 Vec 是一个主要用于数值向量的模板类.我们可以定义向量的类型和组件的数量: Vec<double, 19> myVector 我们还可以使用任何的预定义类型: t ...

最新文章

  1. Pytorch可视化工具tensorboardX(安装不踩坑)
  2. 关于Timer的用法,先简单记下,稍后编辑
  3. rhel7安装oracle11g 的配置和安装过程
  4. 慕课网_《RabbitMQ消息中间件极速入门与实战》学习总结
  5. Visual C# 2010从入门到精通
  6. raspberry pi_Raspberry Pi,CNC铣削,WTF,Cypht,HomeBank,Wekan等的使用方法
  7. java文件下载用什么技术_Java中实现文件上传下载的三种解决方案(推荐)
  8. 【Spring】Spring NoSuchMethodError okhttp3.internal.platform.Platform.log(ILjava/lang/String;Ljava/lan
  9. 计算机基础知识187,中职计算机基础 (187)(11页)-原创力文档
  10. 深入biztalk消息以及消息订阅发布路由机制(四)-消息的轮询和执行
  11. vue3.0 音频插件(vue-aplayer)
  12. 一个人能不能月薪过万,放个小长假就知道了
  13. Skyscrapers (easy version)
  14. html相册制作成视频,怎么把照片制作成视频,视频相册制作免费软件|特效多多
  15. 产品运营都必须知道的数据指标们
  16. DFS深度优先搜索算法(适合初学者)
  17. Transfer Learning Toolkit (TLT) + DeepStream (DS)快速部署深度学习模型(以口罩检测为例)
  18. php----stream_select函数用法
  19. 测试过程bug积累-搜索推荐
  20. Game boy模拟器(6):输入

热门文章

  1. 关于代码手写UI,xib和StoryBoard
  2. pytorch如何定义损失函数_对比PyTorch和TensorFlow的自动差异和动态模型
  3. java中重新加载指定文件_java-更改后重新加载属性文件
  4. flex 平铺布局_flex布局及各种布局的总结
  5. usb3.0 linux无法识别,USB3.0接口不能识别U盘的解决方法
  6. multiprocessing.manager管理的对象需要加锁吗_Go: 内存管理和分配
  7. 梯度下降法预测波士顿房价以及简单的模型评估
  8. Java线程类void setContextClassLoader(ClassLoader loader)方法,带示例
  9. python程序生成exe_使用Python程序生成QR代码的Python程序
  10. c++ stl队列初始化_声明,初始化和访问向量| C ++ STL