迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

用 C++ 编写系统调用

作者:迹忆客 最近更新:2023/08/29 浏览次数:

本文将讨论从 C++ 编写的程序中调用写入系统的方法。 首先,我们将快速刷新系统调用,特别是 write 系统调用及其原型。

稍后,我们将讨论从 C++ 程序调用 write 系统调用。


C++ 中的系统调用

每个操作系统都通过系统调用提供一组服务。 它是计算机程序向操作系统请求服务的一种机制。

系统调用提供以下服务:

  1. 流程创建和管理
  2. 主存管理
  3. 文件和文件系统管理
  4. 设备输入/输出
  5. 保护
  6. 联网

程序所需的最频繁的服务是输入/输出。 接下来,我们将讨论 write 系统调用。

程序通过 write 系统调用请求底层操作系统在某些设备上写入。

在进行写入调用之前,了解文件描述符很重要。

文件描述符

在 Unix 和基于 Unix 的操作系统中,文件描述符是唯一标识文件或其他 IO 资源(如套接字或管道)的数字。

通常,文件描述符是一个非负整数值。 程序通过文件描述符访问文件进行IO。

库函数处理 IO 并以文件描述符作为参数。

第一步是按名称打开文件(如果文件不在程序文件夹中,则为绝对/相对路径)以访问文件以进行 IO。

如果 open 函数成功打开一个文件(即,存在同名文件并且用户具有所需的权限),它将返回一个文件描述符。

int fd = open("abc.txt", O_RDONLY | O_CREAT);

open 函数有两个参数。 第一个参数是文件名,第二个参数是读取模式(例如只读模式、只写模式等)。

后续对文件的IO操作都是通过文件描述符进行的。


C++ 中的 write 系统调用

write系统调用是操作系统内核提供的最基本的例程之一。 它将数据从主内存(缓冲区)写入文件(存储在某些硬件设备上)。

write() 系统调用将 buf 指向的内存缓冲区中最多 count 个字节写入文件描述符引用的文件。

它是一个低级函数,只能理解字节。 write 调用不能用于写入记录,例如类。

因此,更高级别的输入输出函数(如 printf())不可避免地要执行复杂的 I/O。

我们首先看一下用于将数据写入文件的 write 系统调用的语法。

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

write函数的三个参数详细信息是:

  1. 文件描述符 fd 是从打开文件的调用中获得的。 它是一个整数值。 还可以分别为标准输入、标准输出和标准错误指定值 0、1 和 2。
  2. 指向内存中缓冲区 buf 的指针,数据存储在主内存中。
  3. count 指定要从缓冲区 buf 写入 fd 指向的文件的字节数。

类型 ssize_t 和 size_t 分别是 stddef.h 中定义的有符号和无符号整数数据类型。

返回值

write 函数返回一个带符号的值。 成功时,它返回成功写入文件的字节数,有时可能小于指定的计数。

总写入字节数小于计数的可能原因可能是输出设备内存已满,或者源写入缓冲区要写入的字符数少于计数中指定的数量。

出错时,write 系统调用返回 -1,并设置 errno 来指示遇到的错误。

在这里,我们有一个完整的程序可以使用 write 系统调用写入文件。

#include<fcntl.h>
#include<errno.h>
#include<iostream>

extern int errno;

using namespace std;

int main() {
    int fd, count;
    fd = open("abc.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    cout << "File descriptor = " << fd << '\n';
    if (fd == -1) {
        // print which type of error have in a code
        printf("Error Number % d\n", errno);
        // print program detail "Success or failure"
        perror("Program");
    }
    char buff[]="This is a test program to check write system call.";
    count = write(fd, buff, 50);
    if (count == -1)
        cout << "Error writing in file";
    else
        cout << "Number of bytes written to the file: " << count << '\n';
    close(fd);
    return 0;
}

第一个头文件 fcntl.h 有一个 write 系统调用。 第二个头文件有错误函数。

在 open 函数调用中,我们以写入模式创建一个新文件名 abc.txt。 该文件之前可能存在,但使用 O_TRUNC 时,之前的内容将被删除,并创建一个新的空文件。

代码0644表示文件权限。 接下来,if 条件检查文件是否成功打开。

如果失败,将显示错误消息。

接下来,我们使用示例文本创建了一个字符数组(用作缓冲区)。 最后,我们写入文件。

第三个参数是 50,表示要从 buff 数组写入的字符数。

计数是从 write() API 调用返回的整数值。 如果失败,该值为-1; 因此,我们检查计数并相应地打印错误消息。

如果写入操作成功,我们将得到一个正值的 count,并且 if 条件将显示成功写入文件的总字节数。

第一个输出值 3 显示文件已成功打开。 第二行50表示50个字节全部写入成功。

接下来,我们修改了 open 语句。

fd = open("abc.txt", O_RDONLY | O_CREAT | O_TRUNC, 0644);

请注意,我们已将 O_WRONLY 替换为 O_RDONLY,结果是,输出为:

File descriptor = -1
Error Number  13
Program: Permission denied
Error writing in file

我们的打开操作失败,因为不可能通过截断内容来以读取模式打开现有文件。

由于失败,您可以看到文件描述符为-1。 另外,写入操作也不成功。

如果我们在 write 系统调用之前关闭文件,结果将是 write 系统调用操作不成功。 在这种情况下,输出应该是这样的:

File descriptor = 3
Error writing in file

这里,文件描述符不为-1,但文件已关闭; 因此,write 系统调用失败。

write系统调用返回的值为-1。 因此,会打印一条错误消息。

上一篇:在 C++ 中获取鼠标位置

下一篇:没有了

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 C++ 中获取鼠标位置

发布时间:2023/08/28 浏览次数:136 分类:C++

本文讲述如何在 C++ 中获取鼠标位置。在 C++ 中获取鼠标位置 C++ 提供了 GetCursorPos 方法来获取鼠标光标的 x 和 y 位置。

C++ 中的多维向量

发布时间:2023/08/28 浏览次数:150 分类:C++

这个简短的编程教程是关于 C++ 中多维向量的介绍。 向量是可以像 C++ 中的动态数组一样存储数据的容器,具有自动调整大小的功能。C++ 中的多维向量

在 C++ 中释放 std::vector 对象

发布时间:2023/08/28 浏览次数:52 分类:C++

本文将解释如何在 C++/C 中释放 std::vector 对象。 首先,我们将了解释放的自编码方式,然后,我们将研究如何在 C++ 中动态释放 std::vector 对象。在 C++ 中释放对象

在 C++ 中计算两个向量之间的角度

发布时间:2023/08/28 浏览次数:173 分类:C++

矢量数学是处理矢量的数学分支,矢量是具有大小和方向的几何对象。 例如,向量尾部形成的角度等于两个向量形成的角度

调整 2D 矢量大小 C++

发布时间:2023/08/28 浏览次数:138 分类:C++

在这篇短文中,我们将重点讨论如何在 C++ 中调整 2d 向量的大小。在 C++ 中调整 2D 矢量大小 要在 C++ 中调整二维向量的大小,我们需要使用名为 resize() 的函数

C++ 中的向量迭代器

发布时间:2023/08/28 浏览次数:163 分类:C++

本文介绍如何在 C++ 中迭代向量。C++ 提供了许多迭代向量的方法。 这些方法称为迭代器,它指向STL容器的内存地址;

使用 C++ 将文件读入二叉搜索树

发布时间:2023/08/27 浏览次数:52 分类:C++

本文将讨论将文件读入 C++ 中的二叉搜索树。 首先,我们将快速讨论二叉搜索树及其操作。稍后我们将看到如何将文件读入二叉搜索树。C++ 中的二叉搜索树

C++中逐级打印二叉树中的数据

发布时间:2023/08/27 浏览次数:183 分类:C++

二叉树的逐层遍历称为广度优先遍历。 本教程将教您如何使用 C++ 逐级打印二叉树中的数据,并让您熟悉执行此任务的不同方法。

用 C++ 构建解析树

发布时间:2023/08/27 浏览次数:100 分类:C++

本文将教授三种主要的 C++ 方法来在 C++ 中构建解析树。 第一种方法使用选择语句 if (条件) 语句和 if (条件) 语句 else 语句。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便