【Linux操作系统】深入理解系统调用中的read和write函数

在操作系统中,系统调用是用户程序与操作系统之间进行交互的重要方式。其中,read和write函数是常用的系统调用函数,用于在用户程序和操作系统之间进行数据的读取和写入。本文将深入介绍read和write函数的工作原理、用法以及示例代码,以帮助读者更好地理解和应用这两个函数。
在这里插入图片描述

文章目录

    • 1. read函数的工作原理及用法:
      • 1.1 函数原型和参数
      • 1.2 代码举例
      • 1.3 代码解释
    • 2. write函数的工作原理及用法:
      • 2.1 函数原型和参数
      • 2.2 代码举例
      • 2.3代码解释
    • 3. 文件描述符
      • 3.1 进程控制块
      • 3.2 什么是文件操作符
      • 3.3 特殊的文件描述符

1. read函数的工作原理及用法:

1.1 函数原型和参数

read函数用于从文件描述符中读取数据,并将数据存储到缓冲区中。

其函数原型如下:

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

其中,fd是文件描述符,buf是存放读取数据的缓冲区,count是要读取的字节数。read函数返回实际读取的字节数,如果返回 -1 表示读取失败。

官方手册的解释:
 
在这里插入图片描述

1.2 代码举例

下面是一个使用read函数从文件中读取数据的示例代码:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main() {
    int fd = open("file.txt", O_RDONLY);
    char buffer[1024];
    ssize_t bytesRead = read(fd, buffer, sizeof(buffer));
    if (bytesRead == -1) {
        perror("read");
        return 1;
    }
    printf("Read %ld bytes: %s\n", bytesRead, buffer);
    close(fd);
    return 0;
}

1.3 代码解释

在上述示例代码中,首先使用open函数打开一个名为file.txt的文件,并以只读方式打开。然后,read函数从文件中读取数据,并将数据存储到buffer中,最后通过printf函数输出读取的数据。

2. write函数的工作原理及用法:

2.1 函数原型和参数

write函数用于将数据从缓冲区写入到文件描述符中。

其函数原型如下:

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

其中,fd是文件描述符,buf是存放待写入数据的缓冲区,count是要写入的字节数。write函数返回实际写入的字节数,如果返回 -1 表示写入失败。

官方手册的解释:

在这里插入图片描述

2.2 代码举例

下面是一个使用write函数将数据写入文件的示例代码:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main() {
    int fd = open("file.txt", O_WRONLY | O_CREAT, 0644);
    char *data = "Hello, world!";
    ssize_t bytesWritten = write(fd, data, strlen(data));
    if (bytesWritten == -1) {
        perror("write");
        return 1;
    }
    printf("Written %ld bytes\n", bytesWritten);
    close(fd);
    return 0;
}

2.3代码解释

在上述示例代码中,首先使用open函数创建一个名为file.txt的文件,并以只写方式打开。然后,write函数将字符串"Hello, world!"写入到文件中,最后通过printf函数输出写入的字节数。

3. 文件描述符

3.1 进程控制块

进程控制块(Process Control Block,PCB)是操作系统中用于管理和控制进程的数据结构。每个正在运行或等待运行的进程都有一个对应的PCB,它包含了进程的各种属性和状态信息。

PCB通常是一个数据结构,其中包含了以下信息:

  1. 进程标识符(Process Identifier,PID):用于唯一标识一个进程。
  2. 程序计数器(Program Counter,PC):记录了下一条要执行的指令的地址。
  3. 寄存器集合:包括通用寄存器、指令寄存器、栈指针等,用于保存进程的上下文信息。
  4. 进程状态(Process State):表示进程的当前状态,如运行、就绪、等待等。
  5. 进程优先级(Process Priority):用于确定进程在调度时的优先级顺序。
  6. 进程调度信息:包括进程的调度策略、时间片大小等。
  7. 进程资源管理信息:包括进程所拥有的资源、打开的文件等。
  8. 父进程标识符(Parent Process Identifier,PPID):记录了创建该进程的父进程的PID。
  9. 进程创建时间和运行时间:记录了进程的创建时间和运行时间。
  10. 内存管理信息:包括进程的内存分配情况、页面表等。
  11. 文件描述符表:记录了进程打开的文件和对应的文件描述符。

PCB是操作系统中非常重要的数据结构,它存储了进程的所有关键信息,使得操作系统能够对进程进行管理和调度。当操作系统需要切换进程时,会保存当前进程的上下文信息到其对应的PCB中,并加载下一个进程的上下文信息。这样可以实现进程的切换和并发执行。

3.2 什么是文件操作符

文件描述符可以被看作是操作系统为了管理打开的文件或设备而分配的一个标识符。它是一个整数值,用于标识一个特定的文件或设备。

想象一下,你在操作系统中打开了一个文件或设备,比如一个文本文件或一个串口设备。操作系统会为这个文件或设备分配一个文件描述符,并将其返回给你。这个文件描述符就像是一个门牌号,用于标记这个文件或设备

当你想对这个文件或设备进行读取写入关闭等操作时,你只需要告诉操作系统使用这个文件描述符,操作系统就会知道你要操作的是哪个文件或设备。

文件描述符的具体值是一个非负整数,通常从0开始递增。操作系统会使用一个文件描述符表来记录所有打开的文件或设备的信息,包括文件的位置、读写权限等。当你使用文件描述符进行操作时,操作系统会根据文件描述符找到对应的文件信息,并执行相应的操作。

在这里插入图片描述

3.3 特殊的文件描述符

  1. 标准输入(Standard Input,STDIN):标准输入文件描述符,通常用整数值0表示;在C语言中,可以使用宏定义STDIN_FILENO来表示标准输入。它用于接收用户的输入,比如键盘输入。
#include <unistd.h>

int main() {
    char buffer[100];
    ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer));
    // 从标准输入读取数据
    // ...
    return 0;
}
  1. 标准输出(Standard Output,STDOUT):通常用整数值1来表示。在C语言中,可以使用宏定义STDOUT_FILENO来表示标准输出。它用于向屏幕或终端输出信息。
#include <unistd.h>

int main() {
    char buffer[] = "Hello, World!";
    ssize_t bytesWritten = write(STDOUT_FILENO, buffer, sizeof(buffer));
    // 将数据输出到标准输出
    // ...
    return 0;
}
  1. 标准输入(Standard Input,STDIN):通常用整数值2来表示。在C语言中,可以使用宏定义STDERR_FILENO来表示标准错误。它用于接收用户的输入,比如键盘输入。
#include <unistd.h>
#include <stdio.h>

int main() {
    fprintf(stderr, "An error occurred!\n");
    // 输出错误信息到标准错误
    // ...
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/71563.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

湘大 XTU OJ 1290 Alice and Bob 题解(非常详细):字符串 分类讨论 简单模拟

一、链接 1290 Alice and Bob 二、题目 题目描述 Alice和Bob玩剪刀-石头-布的游戏&#xff0c;请你写个程序判断一下比赛的结果。 输入 第一行是一个整数K&#xff0c;表示样例的个数。 以后每行两个单词&#xff0c;rock表示石头&#xff0c;paper表示布&#xff0c;scis…

Redis 拒绝服务漏洞(CVE-2023-28856)修复处理

一、漏洞描述 Redis Labs Redis是美国Redis Labs公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值&#xff08;Key-Value&#xff09;存储数据库&#xff0c;并提供多种语言的API。 Redis 7.0.0 到 7.0.10版本、6.2.0 到 6.2.11版本、6.0.0 到 …

Git:在本地电脑上如何使用git?

git 版本&#xff1a; 2.40.1.windows.1 文章目录 一. 使用git之前你必须要理解的几个概念1.1 理解工作区、版本库、暂存区的概念1.2 提交Git版本库的步骤【分两步执行】 二. Git本地库实战2.1 初始化版本库2.2 新建 & 提交 & 状态2.3 查看日志2.4 回退 & 穿梭 &am…

树莓派RP2040 用Arduino IDE安装和编译

目录 1 Arduino IDE 1.1 IDE下载 1.2 安装 arduino mbed os rp2040 boards 2 编程-烧录固件 2.1 打开点灯示例程序 2.2 选择Raspberry Pi Pico开发板 2.3 编译程序 2.4 烧录程序 2.4.1 Raspberry Pi Pico开发板首次烧录提示失败 2.4.2 解决首次下载失败问题 2.4.2.1…

FFmpeg 使用总结

FFmpeg 简介 FFmpeg的名称来自MPEG视频编码标准&#xff0c;前面的“FF”代表“Fast Forward”&#xff0c;FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换。包括如下几个部分&#xf…

C语言一些有趣的冷门知识

文章目录 概要1.访问数组元素的方法运行结果 2.中括号的特殊用法运行结果 3.大括号的特殊用法运行结果 4.sizeof的用法运行结果 5.渐进运算符运行结果 小结 概要 本文章只是介绍一些有趣的C语言知识&#xff0c;纯属娱乐。这里所有的演示代码我是使用的编译器是Visual Studio …

jenkins流水线

1.拉取代码 https://gitee.com/Wjc_project/yygh-parent.git2、项目编译 mvn clean package -Dmaven.test.skiptrue ls hospital-manage/target3、构建镜像 ls hospital-manage/target docker build -t hospital-manage:latest -f hospital-manage/Dockerfile ./hospital-ma…

SRS视频媒体服务器-docker启动:更换默认端口时的错误

一、概述 在使用srs视频服务器时&#xff0c;一直都是使用默认的端口配置。但是&#xff0c;这些默认端口在某些时候可能已经被占用了&#xff0c;就需要更改端口了。 注意注意注意&#xff1a;使用docker启动srs&#xff0c;在更换端口一定要下面的内容。 二、使用docker启动…

MFC第三十天 通过CToolBar类开发文字工具栏和工具箱、GDI+边框填充以及基本图形的绘制方法、图形绘制过程的反色线模型和实色模型

文章目录 CControlBar通过CToolBar类开发文字工具栏和工具箱CMainFrame.hCAppCMainFrm.cppCMainView.hCMainView.cppCEllipse.hCEllipse.cppCLine.hCLine.cppCRRect .hCRRect .cpp CControlBar class AFX_NOVTABLE CControlBar : public CWnd{DECLARE_DYNAMIC(CControlBar)pro…

Jmeter请求接口返回值乱码解决

乱码示例 解决步骤&#xff1a; 1.打开Jmeter安装目录下的bin目录&#xff0c;找到jmeter.properties 2.使用记事本或其他编译工具打开jmeter.properties文件&#xff0c;然后全局搜索sampleresult.default.encoding 3.在文件中添加sampleresult.default.encodingutf-8,保存…

LeetCode--HOT100题(28)

目录 题目描述&#xff1a;2. 两数相加&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;2. 两数相加&#xff08;中等&#xff09; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且…

c语言每日一练(6)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

42. range函数—生成器函数-更新

【目录】 文章目录 1. range( )函数是什么&#xff1f;2. 知识回顾-列表的切片3. range( )函数的语法3.1 range( )函数语法3.2 参数说明3.3 列表切片和range函数的区别 4. 实操练习4.1 参数为一个正整数4.2 参数为04.3 参数为一个负整数4.4 有2个参数4.5 有3个参数4.6 步长为负…

vscode extension 怎么区分dev prod

开发模式注入环境变量 使用vsode 提供的api

利用Torchmetrics库快速进行Torch的评价指标计算(推荐)

目录 1、安装 2、基本流程介绍 3、MetricCollection 4、自定义指标 5、我们可以调用多个指标计算不同的任务 6、可以是标签,也可以是one_hot编码 7、常用分类指标计算 8、异常报错 1、安装 官网地址:Welcome to TorchMetrics — PyTorch-Metrics 1.0.1 documenta…

掌握Python的X篇_34_Python朗读文字

各种广告中说python是人工智能的主宰&#xff0c;其实这更多是噱头的成分&#xff0c;但是python确实可以做很多的事情&#xff0c;本篇将会介绍利用pythonAI平台来合成声音。今天将会用到的是百度。 文章目录 1. baiToVoice2. 注册appid3. 合成代码 1. baiToVoice 使用百度A…

创建多图层叠加效果的背景与人物图像

引言&#xff1a; 在现代应用程序开发中&#xff0c;图形资源的使用是非常常见的&#xff0c;特别是在用户界面设计中。通过使用TImageList和TGlyph组件的组合&#xff0c;我们可以实现令人印象深刻的多图层叠加效果。本文将介绍如何使用这两个组件来创建背景和人物的多图层叠加…

Idea创建maven管理的web项目

如果你想在项目中添加一个传统的 src 目录来存放源代码&#xff0c;可以按照以下步骤操作&#xff1a; 1. 在项目视图中&#xff0c;右键单击项目名称&#xff0c;选择 “New” -> “Directory”。 2. 在弹出的对话框中&#xff0c;输入目录名称为 “src”&#xff0c;然后…

Camunda 7.x 系列【3】Camunda 简介

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址&#xff1a;https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 概述2. 核心组件2.1 流程引擎2.2 模型2.3 Web…

金融反欺诈的应用实践

“根据980起全球重大金融欺诈事件分析&#xff0c;60%的欺诈发生在移动端&#xff0c;同比增长170%。“&#xff0c;在香港近日举办的金融科技沙龙上&#xff0c;顶象金融业务安全专家史博表示&#xff0c;金融业已成为不法分子重要的攻击对象。 本届金融科技沙龙由Databricks…