Linux | 探究C语言文件接口与Linux系统文件接口的区别与联系 | fopen和open的区别与联系

news2024/9/26 5:21:23

什么是尘土?从大地之肺发出的一声叹息。 - 《阿多尼斯诗集》(阿多尼斯)

2024.8.23

目录

1、C语言IO接口

示例代码:使用 fopen 和 fclose 读写文件

示例1:通过write写文件

示例2:通过read写文件

C语言的标准流:stdin、stdout和stderr

stdin (标准输入流)

stdout (标准输出流)

stderr (标准错误流)

标准流总结:

示例代码:使用标准流与外部设备进行设备交互

2、Linux系统IO接口与库函数

系统IO接口介绍:open

参数说明

返回值

注意事项

示例代码:使用系统调用进行文件操作

示例1:通过系统调用接口write写文件

示例2:用过系统调用接口read读文件

3、C语言IO接口和Linux系统IO接口的区别与联系

区别

抽象级别:

可移植性:

功能丰富性:

联系

封装关系:

共同目标:

互操作性:

文件描述符:

底层支持:


在C语言编程中,文件IO操作是基础而重要的部分。通过文件IO,程序能够读取外部数据或将结果持久化存储。

1、C语言IO接口

C语言提供了丰富的文件操作API,基于标准库中的 <stdio.h> 头文件。最常用的文件操作包括打开、读取、写入、关闭文件等。

示例代码:使用 fopenfclose 读写文件
示例1:通过write写文件
#include<stdio.h>
#include<string.h>
// 通过write写文件
int main()
{
  FILE* fp = fopen("test.txt", "a");
  if(!fp)
  {
    printf("file open fail\n");
    return -1;
  }

  const char* msg = "hello world\n";
  int len = strlen(msg);
  int count = 10;
  while(count--)
  {
    fwrite(msg, 1, len, fp);
  }

  fclose(fp);

  return 0;
}
示例2:通过read写文件
#include<stdio.h>
#include<string.h>
#define MAX 1024
// 通过read写文件
int main()
{
  FILE* fp = fopen("test.txt", "r");
  if(!fp)
  {
    printf("[error] file open fail\n");
    return -1;
  }
  int cnt = 0;
  char buf[MAX];
  const char* msg = "hello world\n";
  while(1)
  {
    cnt++;
    if(feof(fp))
    {
      break;
    }
    printf("cnt -> %d\n",cnt);
    size_t size = fread(buf, 1, strlen(msg), fp);
    printf("%s\n", buf);
  }
  fclose(fp); 
  
  return 0;
}

C语言的标准流:stdin、stdout和stderr
stdin (标准输入流)
  • 类型FILE*
  • 作用:用于从键盘或另一个输入设备读取数据。
  • 文件指针:通常指向文件描述符 0
stdout (标准输出流)
  • 类型FILE*
  • 作用:用于向控制台或终端输出数据。
  • 文件指针:通常指向文件描述符 1
stderr (标准错误流)
  • 类型FILE*
  • 作用:用于向控制台或终端输出错误信息。与 stdout 不同,stderr 通常用于输出错误或诊断信息,即使程序的输出被重定向,错误信息仍然会显示在终端上。
  • 文件指针:通常指向文件描述符 2
标准流总结:
  • 全局性:在任何C程序中,无需打开即可使用。
  • 缓冲stdoutstderr 通常具有不同的缓冲行为。stdout 可能是行缓冲或全缓冲,而 stderr 通常是无缓冲的。也就是说,stdout 可能不会立即输出内容,但 stderr 是为了快速错误报告而设计的,通常会立即输出。
  • 重定向:可以通过简单的重定向操作改变它们的输出目标,例如在 shell 中使用 >2> 将输出重定向到文件。
  • 可以通过 fileno 函数获取 FILE* 指针对应的文件描述符,例如 fileno(stdin) 将返回 0
  • 在多线程程序中,stdoutstderr 不是线程安全的,但 stderr 在写入时通常会被锁定以避免与其他线程冲突。
示例代码:使用标准流与外部设备进行设备交互
#include <stdio.h>

int main() {
    char buffer[256];

    // 使用 stdin 读取键盘数据
    printf("Enter some text: ");
    fgets(buffer, sizeof(buffer), stdin);

    // 使用 stdout 向显示器输出数据
    fprintf(stdout, "You entered: %s\n", buffer);

    // 使用 stderr 向显示器输出错误信息
    fprintf(stderr, "This is an error message.\n");

    return 0;
}

2、Linux系统IO接口与库函数

系统调用是操作系统提供给用户程序的接口,而库函数则是对这些系统调用的封装,使得程序员可以使用更高级、更易用的API。

系统IO接口介绍:open

在Linux系统中,open 系统调用是一个用于打开文件或创建新文件的标准函数。它提供了一种底层的方法来操作文件,与C标准库中的 fopen 函数相比,open 函数更接近操作系统层面,允许更细致地控制文件的打开方式和属性。

#include <sys/types.h>  // 包含系统类型定义
#include <sys/stat.h>   // 包含文件状态结构定义
#include <fcntl.h>      // 包含文件控制选项定义

int open(const char *pathname, int flags, ... /* mode_t mode */);
参数说明
  1. pathname:这是一个指向以null结尾的字符串的指针,表示要打开或创建的文件的路径。
  2. flags:这是一个整数,用于指定文件打开的各种选项和模式。可以是以下宏的组合:
    • O_RDONLY:以只读方式打开文件。
    • O_WRONLY:以只写方式打开文件。
    • O_RDWR:以读写方式打开文件。
    • O_CREAT:如果文件不存在,创建新文件。
    • O_EXCL:与 O_CREAT 一起使用时,如果文件已存在,则 open 调用失败。
    • O_TRUNC:如果文件存在,将其截断为零长度。
    • O_APPEND:所有写操作都追加到文件末尾,忽略 lseekllseek 设置的文件偏移量。
    • 等等,还有其他标志位用于更特殊的用途。
  3. mode(可选):当使用 O_CREAT 标志时,这个参数指定新创建文件的权限模式。如果不提供,则默认权限由进程的 umask 值决定(就近原则)。
返回值
  • 成功时,open 函数返回一个非负的文件描述符(fd),用于在后续操作中标识打开的文件。
  • 失败时,返回 -1,并设置全局变量 errno 以指示错误类型。
注意事项
  • open 函数返回的文件描述符(fd)可以用于后续的 readwritelseek 等系统调用。
  • 使用 open 打开的文件应该在不再需要时使用 close 函数关闭,以释放系统资源。
  • open 函数支持的 flags 标志位非常灵活,可以根据需要组合使用不同的标志来控制文件的打开方式。
  • fopen 不同,open 没有提供缓冲机制。如果需要缓冲,可以使用标准IO库中的缓冲函数,或者手动实现缓冲逻辑。

write、read、close和C语言接口类似 不多介绍啦~

示例代码:使用系统调用进行文件操作
示例1:通过系统调用接口write写文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main() {
    // 设置文件的默认权限掩码,创建文件时忽略进程的umask设置
    umask(0);

    // 打开文件,O_WRONLY 只写模式,O_CREAT 如果文件不存在则创建,0644 是文件的默认权限
    int fd = open("myfile", O_WRONLY | O_CREAT, 0644);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    // 定义要写入的消息和次数
    int count = 5;
    const char *msg = "hello bit!\n";
    int len = strlen(msg);

    // 循环写入消息
    while (count--) {
        // write 系统调用,将 msg 缓冲区中 len 大小的数据写入到文件描述符 fd 指向的文件
        // 返回值是实际写入的字节数
        ssize_t bytes_written = write(fd, msg, len);
        if (bytes_written < 0) {
            perror("write");
            close(fd);
            return 1;
        }
    }

    // 关闭文件描述符
    close(fd);

    return 0;
}
示例2:用过系统调用接口read读文件
#include <stdio.h>      // 包含标准输入输出库
#include <sys/types.h>  // 包含系统类型定义
#include <sys/stat.h>   // 包含文件状态结构定义
#include <fcntl.h>      // 包含文件控制选项定义
#include <unistd.h>     // 包含Unix标准函数定义,如read和close
#include <string.h>     // 包含字符串函数定义

int main() {
    // 尝试以只读方式打开文件"myfile"
    int fd = open("myfile", O_RDONLY);
    if (fd < 0) {
        // 如果打开失败,打印错误信息并退出程序
        perror("open");
        return 1;
    }

    // 定义要读取的字符串长度,这里假设与写入时相同
    const char *msg = "hello bit!\n";
    size_t msg_len = strlen(msg);
    char buf[1024]; // 定义一个缓冲区用于存储读取的数据

    // 使用循环来读取文件,直到文件结束
    while (1) {
        // 调用read系统调用尝试从文件描述符fd中读取msg_len长度的数据到缓冲区buf
        ssize_t s = read(fd, buf, msg_len);
        if (s > 0) {
            // 如果读取成功,打印缓冲区的内容
            printf("%s", buf);
        } else {
            // 如果读取到文件末尾或发生错误,退出循环
            break;
        }
    }

    // 关闭文件描述符
    close(fd);

    return 0; // 正常退出程序
}

3、C语言IO接口和Linux系统IO接口的区别与联系

C语言IO接口和Linux系统IO接口是两个层面的抽象,它们之间存在明显的区别和紧密的联系:

区别
抽象级别
    • C语言IO接口(如 fopenfclosefreadfwrite 等)是C标准库提供的功能,它们是对底层系统IO操作的高层次抽象。
    • Linux系统IO接口(如 openclosereadwrite 等)是直接由操作系统内核提供的系统调用,提供了对硬件的直接操作能力。
可移植性
    • C语言IO接口具有良好的可移植性,因为它们由编译器和标准库实现,可以在不同的操作系统上运行。
    • Linux系统IO接口是特定于操作系统的,只能在支持这些系统调用的系统上使用。
功能丰富性
    • C语言IO接口提供了更多格式化和方便的函数,如 fprintffgets 等,简化了编程。
    • Linux系统IO接口提供了基础的读写操作,但通常需要程序员进行更多的底层管理。
联系
封装关系
    • C语言IO接口实际上是对Linux系统IO接口的封装。例如,当你使用 fopen 打开一个文件时,C库内部会使用 open 系统调用来获取文件描述符。
共同目标
    • 两者都旨在提供对文件和输入输出流的操作能力,尽管抽象级别不同。
互操作性
    • 程序员可以在使用C语言IO接口的同时,通过特定的函数(如 fileno)获取到底层的文件描述符,并使用Linux系统IO接口进行操作。
文件描述符
    • 无论是使用C语言IO接口还是Linux系统IO接口,最终都可能与文件描述符(fd)打交道。例如,fopen 返回的 FILE* 类型内部包含了一个文件描述符。
底层支持
    • C语言IO接口的实现依赖于操作系统提供的底层支持,如Linux的系统调用来完成实际的文件操作。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

集合及数据结构第十节(上)————优先级队列,堆的创建、插入、删除与用堆模拟实现优先级队列

系列文章目录 集合及数据结构第十节&#xff08;上&#xff09;————优先级队列&#xff0c;堆的创建、插入、删除与用堆模拟实现优先级队列 优先级队列&#xff0c;堆的创建、插入、删除与用堆模拟实现优先级队列 优先级队列的概念堆的概念堆的存储方式堆的创建变量的作…

谷粒商城实战笔记-250-商城业务-消息队列-RabbitMQ安装-Docker

一&#xff0c;docker安装RabbitMq RabbitMQ 是一个开源的消息代理软件&#xff0c;广泛用于实现异步通信和应用程序解耦。 使用 Docker 容器化技术可以简化 RabbitMQ 的安装和部署过程。 以下是使用 Docker 安装 RabbitMQ 的详细步骤。 步骤 1: 安装 Docker 如果您的系统…

Linux 软件编程 网络 tcp

1.TCP粘包问题&#xff1a; TCP发送数据是连续的&#xff0c;两次发送的数据可能粘连成一包被接收到 1.解决粘包问题方法&#xff1a; 1.接收指定长度&#xff1a;&#xff08;不稳定&#xff09; 发送5个字节 接收5个字节 2.睡眠&#x…

【数据库】Mysql 批量变更所有字段类型为varchar的字符集

生成变更语句 SELECT CONCAT(ALTER TABLE , TABLE_NAME, MODIFY , COLUMN_NAME, , COLUMN_TYPE, , CHARACTER SET utf8 COLLATE utf8_general_ci , CASE WHEN IS_NULLABLE YES THEN NULL DEFAULT NULL WHEN IS_NULLABLE NO AND ISNULL(COLUMN_DEFAULT) THEN NOT NULL EL…

Adobe Illustrator矢量绘图软件win/mac软件下载安装

一、软件概述 1.1 Adobe Illustrator简介 Adobe Illustrator是一款由Adobe Systems开发的强大矢量绘图软件&#xff0c;专为设计师、艺术家及图形专家设计。它广泛应用于平面设计、插画、UI设计、图标设计、排版及数字媒体制作等领域。Illustrator以其独特的矢量图形处理能力…

Datawhale X 魔搭 AI夏令营第四期 | AIGC文生图——进阶上分 实战优化 Task3笔记

Hi&#xff0c;大家好&#xff0c;我是半亩花海。在上一个任务中&#xff0c;我们逐行精读baseline&#xff0c;掌握了利用AI工具提升学习效率&#xff0c;并制作了话剧连环画&#xff0c;初步了解Secpter WebUI。今天&#xff0c;我们将深入探讨微调的基本原理及其参数&#x…

海外版多语言互助盘三三复制超级人脉系统

此套源码是全新二开的超级人脉系统&#xff0c;面向海外操作新增多语言&#xff0c;后台可新增其他语言.

【图机器学习系列】(二)从传统机器学习角度理解图(一)

微信公众号&#xff1a;leetcode_algos_life&#xff0c;代码随想随记 小红书&#xff1a;412408155 CSDN&#xff1a;https://blog.csdn.net/woai8339?typeblog &#xff0c;代码随想随记 GitHub: https://github.com/riverind 抖音【暂未开始&#xff0c;计划开始】&#xf…

java 中的设计模式

文章目录 一、前言二、设计模式的分类三、设计模式的原则1、开闭原则&#xff08;Open Close Principle&#xff09;2、里氏代换原则&#xff08;Liskov Substitution Principle&#xff09;3、依赖倒转原则&#xff08;Dependence Inversion Principle&#xff09;4、接口隔离…

【案例55】WebSphere非root用户启动方案

问题背景 很多项目为了安全因素考虑&#xff0c;想让在Linux服务器中启动的程序都用非root用户启动。 解决方案 创建用户和组 现在我们用 root 用户登录&#xff0c;并创建用户和组。 ##创建用户 [rootnc-test ~]# useradd wasadmin##修改密码 [rootnc-test~]# passwd was…

AT 指令和WIFI模组

此次使用到的wifi模组是乐鑫的wifi模组esp8684&#xff0c;该wifi模组内部集成了MQTT协议 串口发送AT指令与单片机进行通信&#xff0c;一下是ESP8684的管脚布局。 ESP8684管脚描述&#xff1a; 注&#xff1a;30 和 31 号管脚是用于调试的管脚&#xff0c;20 与 21 号管脚才是…

allure实现测试报告的生成

在测试用例编写完成之后&#xff0c;我们可以通过allure生成测试报告 一、配置java环境变量&#xff0c;jdk17的版本 二、安装allure-commanlie工具&#xff0c;可在官网下载&#xff0c;也可通过百度网盘下载 链接: https://pan.baidu.com/s/10123Iv2f7Ht476feDiP0Yw 提取码…

视频智能分析平台烟火检测视频安防监控烟火算法识别应用方案

烟火检测算法的应用方案主要围绕其核心技术——深度学习&#xff08;特别是卷积神经网络CNN&#xff09;和计算机视觉技术展开&#xff0c;旨在实现对监控视频中的烟雾和火焰进行实时、准确的检测与识别。以下是一个详细的烟火检测算法应用方案&#xff1a; 一、技术原理 烟火…

如何使用Python进行餐馆满意度分析——K-means算法与NLP情感分析实战

&#x1f393; 作者&#xff1a;计算机毕设小月哥 | 软件开发专家 &#x1f5a5;️ 简介&#xff1a;8年计算机软件程序开发经验。精通Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等技术栈。 &#x1f6e0;️ 专业服务 &#x1f6e0;️ 需求定制化开发源码提…

TOP10漏洞原理

## 本人为学习网安不久的新人&#xff0c;记一次学习笔记&#xff0c;有缺陷或者表述不对的地方欢迎大家指出&#xff0c;感谢&#xff01; ## 1、sql注入&#xff1a;web应用程序对用户输入的数据没有进行过滤&#xff0c;或者过滤不严&#xff0c;就把sql语句拼接进数据库…

【C++ Primer Plus习题】3.2

问题: 解答: #include <iostream> using namespace std;const int FOOT_TO_INCH 12; const double INCH_TO_MI 0.0254; const float KG_TO_POUND 2.2;int main() {int inch 0;int foot 0;int inchs 0;double mi 0;int pound 0;double kg 0;double BMI 0;cout &…

QEMU/KVM 虚拟机显卡透传 (vfio-pci)

首发日期 2024-08-22, 以下为原文内容: 本文介绍将 PCIE 设备 (显卡) 透传给 QEMU/KVM 虚拟机的一种方法, 基于 Linux 内核的 vfio-pci 功能. 透传 (pass through) 之后, 虚拟机内可以直接操作 (使用) 显卡硬件, 就像物理机那样, 几乎没有虚拟化的性能损失. 这里是 穷人小水滴…

电商分账系统整个原理 空中分账具体解决方案

电商分账系统最近比较火&#xff0c;比如大家做天猫的时候&#xff0c;直接可以通过网商贷把钱拿出来&#xff0c;但抖店没有这种贷款&#xff0c;大家都有一种不想进对公的方式&#xff0c;那系统本身就是虚拟户加操作系统&#xff0c;虚拟户是银行开的&#xff0c;银行开就需…

【Java】从零到一使用Feign与Sentinel (详细图解)

Java系列文章目录 补充内容 Windows通过SSH连接Linux 第一章 Linux基本命令的学习与Linux历史 文章目录 Java系列文章目录一、前言二、学习内容&#xff1a;三、问题描述四、解决方案&#xff1a;4.1 认识依赖4.1.1 Feign依赖4.1.2 Sentinel依赖4.1.3 负载均衡依赖4.2 父子项目…

基于 Java Web 的校园驿站管理系统

TOC ssm016基于 Java Web 的校园驿站管理系统jsp 第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。…