当前位置:网站首页>The C Programming Language(第 2 版) 笔记 / 8 UNIX 系统接口 / 8.2 低级 I/O(read 和 write)
The C Programming Language(第 2 版) 笔记 / 8 UNIX 系统接口 / 8.2 低级 I/O(read 和 write)
2022-06-12 16:15:00 【M菜鸟M】
8.2 低级 I/O(read 和 write)
输入与输出是通过 read 和 write 系统调用实现的
在 C 语言程序中,可以通过函数 read 和 write 访问这两个系统调用
这两个函数中,第一个参数是文件描述符,第二个参数是程序中存放读或写的数据的字符数组,第三个参数是要传输的字节数
int n_read = read(int fd, char *buf, int n);
int n_written = write(int fd, char *buf, int n);
每个调用返回实际传输的字节数
在读文件时,函数的返回值可能会小于请求的字节数
如果返回值为 0,则表示已到达文件的结尾,如果返回值为 -1,则表示发生了某种错误
在写文件时,返回值是实际写入的字节数
如果返回值与请求写入的字节数不相等,则说明发生了错误
在一次调用中,读出或写入的数据的字节数可以为任意大小
最常用的值为 1,即每次读出或写入 1 个字符(无缓冲),或是类似于 1024 ~ 4096 这样的与外围设备的物理块大小相应的值
用更大的值调用该函数可以获得更高的效率,因为系统调用的次数减少了
结合以上的讨论,我们可以编写一个简单的程序,将输入复制到输出,这与第 1 章中的复制程序在功能上相同
程序可以将任意输入复制到任意输出,因为输入/输出可以重定向到任何文件或设备
#include "syscalls.h"
main() /* copy input to output */
{
char buf[BUFSIZ];
int n;
while ((n = read(0, buf, BUFSIZ)) > 0)
write(1, buf, n);
return 0;
}
我们已经将系统调用的函数原型集中放在一个头文件 syscalls.h 中
因此,本章中的程序都将包含该头文件,不过,该文件的名字不是标准的
参数 BUFSIZ 也已经在 syscalls.h 头文件中定义
对于所使用的操作系统来说,该值是一个较合适的数值
如果文件大小不是 BUFSIZ 的倍数,则对 read 的某次调用会返回一个较小的字节数write 再按这个字节数写,此后再调用 read 将返回 0
为了更好地掌握有关概念,下面来说明如何用 read 和 write 构造类似于 getchar、putchar 等的高级函数
例如,以下是 getchar 函数的一个版本,它通过每次从标准输入读入一个字符来实现无缓冲输入
#include "syscalls.h"
/* getchar: unbuffered single character input */
int getchar(void)
{
char c;
return (read(0, &c, 1) == 1) ? (unsigned char) c : EOF;
}
其中,c 必须是一个 char 类型的变量,因为 read 函数需要一个字符指针类型的参数(&c)
在返回语句中将 c 转换为 unsigned char 类型可以消除符号扩展问题
getchar 的第二个版本一次读入一组字符,但每次只输出一个字符
#include "syscalls.h"
/* getchar: simple buffered version */
int getchar(void)
{
static char buf[BUFSIZ];
static char *bufp = buf;
static int n = 0;
if (n == 0) {
/* buffer is empty */
n = read(0, buf, sizeof buf);
bufp = buf;
}
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
}
如果要在包含头文件 <stdio.h> 的情况下编译这些版本的 getchar 函数
就有必要用 #undef 预处理指令取消名字 getchar 的宏定义,因为在头文件中,getchar 是以宏方式实现的
边栏推荐
- The C Programming Language(第 2 版) 笔记 / 8 UNIX 系统接口 / 8.3 open、creat、close、unlink
- 5-5 configuring MySQL replication log point based replication
- acwing 797 差分
- Dongmingzhu talks about batteries: the most essential thing is safety
- 国产CPLD中AG1280Q48进行开发的实践之一:思路分析
- acwing 790. 数的三次方根(浮点数二分)
- redis String类型常见命令
- Chapter I linear table
- 借助SpotBugs将程序错误扼杀在摇篮中
- Kill program errors in the cradle with spotbugs
猜你喜欢

< 山东大学软件学院项目实训 > 渲染引擎系统——基础渲染器(七)

acwing 790. 数的三次方根(浮点数二分)

< 山东大学软件学院项目实训 > 渲染引擎系统——基础渲染器(四)

Writing code can also be classified as "manual" or "vulgar", and we should be good at finding good hands!

聊聊事件监听那些事-上

IDEA中文棱形乱码错误解决方法--控制台中文输出棱形乱码

Redis General Command

redis 通用命令

Project training of Software College of Shandong University rendering engine system basic renderer (III)

Office VR porn, coquettish operation! The father of Microsoft hololens resigns!
随机推荐
MYSQL---服务器配置相关问题
[OWT server] customized script 3: server construction
The C Programming Language(第 2 版) 笔记 / 8 UNIX 系统接口 / 8.5 实例(fopen 和 getc 函数的实现)
联通网管协议框图
Chapter I linear table
Kill program errors in the cradle with spotbugs
Sha6 of D to large integer
Example of bit operation (to be continued)
华为设备配置CE双归属
glibc 内存管理模型 释放 C库内存缓存
< 山东大学软件学院项目实训 > 渲染引擎系统——辐射预计算(九)
聊聊事件监听那些事-上
Project training of Software College of Shandong University rendering engine system basic renderer (V)
Dongmingzhu talks about batteries: the most essential thing is safety
Explore the Apache shardingsphere SQL parse format function
Decision tree classification and examples
acwing795 前缀和(一维)
redis String类型常见命令
Step by step steps to create an ABAP program with a custom screen
leetcode-54. Spiral matrix JS