文件理解:从C标准库到系统调用

目录

一、C 标准库文件操作

1. 文件的写入

2. 文件的读取

3. 数据输出到显示器

4. 标准输入输出流

二、C 标准库文件操作模式

三、系统调用文件操作

1. 文件的打开与描述符

2. 文件的读取

3. 文件操作标志

4. 文件权限

5. 文件描述符

四、C 标准库与系统调用的比较

1. 功能对比

2. 底层交互

3. 使用场景


一、C 标准库文件操作

1. 文件的写入

以下是一个使用 C 标准库函数 fwrite 写入文件的示例:

#include <stdio.h>
#include <string.h>int main() 
{FILE *fp = fopen("myfile", "w"); // 以写模式打开文件if (!fp) {printf("fopen error!\n");return 1;}const char *msg = "hello bit!\n";int count = 5;while (count--) {fwrite(msg, strlen(msg), 1, fp); // 将字符串写入文件}fclose(fp); // 关闭文件return 0;
}
  • fopen 函数用于打开或创建文件。"w" 模式表示以写模式打开文件,如果文件不存在则创建一个新文件,如果文件存在则清空其内容

  • fwrite 函数将指定内存区域的内容写入文件。第一个参数是内存区域的指针,第二个参数是每个元素的大小,第三个参数是元素的数量,第四个参数是文件指针。

  • fclose 函数用于关闭文件,释放与文件相关的资源。

2. 文件的读取

以下是一个使用 C 标准库函数 fread 读取文件的示例:

#include <stdio.h>
#include <string.h>int main() 
{FILE *fp = fopen("myfile", "r"); // 以读模式打开文件if (!fp) {printf("fopen error!\n");return 1;}char buf[1024];const char *msg = "hello bit!\n";while (1) {ssize_t s = fread(buf, 1, strlen(msg), fp); // 从文件中读取数据到缓冲区if (s > 0) {buf[s] = 0; // 将缓冲区内容转换为字符串printf("%s", buf);}if (feof(fp)) {   // 检查是否到达文件末尾break;}}fclose(fp);return 0;
}
  • fopen 函数以读模式打开文件。

  • fread 函数从文件中读取数据到指定的缓冲区。第一个参数是缓冲区的指针,第二个参数是每个元素的大小,第三个参数是元素的数量,第四个参数是文件指针。

  • feof 函数用于检查文件是否已到达末尾。

3. 数据输出到显示器

以下是一个使用多种方法将数据输出到显示器的示例:

#include <stdio.h>
#include <string.h>int main() 
{const char *msg = "hello fwrite\n";fwrite(msg, strlen(msg), 1, stdout); // 使用 fwrite 输出到标准输出printf("hello printf\n"); // 使用 printf 输出fprintf(stdout, "hello fprintf\n"); // 使用 fprintf 输出return 0;
}
  • stdout 是标准输出流,指向显示器。

  • fwriteprintffprintf 都可以将数据输出到标准输出流。

4. 标准输入输出流

C 语言默认提供三个标准输入输出流:

  • stdin:标准输入流,默认为键盘输入。

  • stdout:标准输出流,默认为显示器输出。

  • stderr:标准错误流,默认为显示器输出。

以下是一个示例:

#include <stdio.h>
#include <string.h>int main() 
{char buf[1024];ssize_t s = read(0, buf, sizeof(buf)); // 从标准输入(文件描述符0)读取if (s > 0) {buf[s] = 0;write(1, buf, strlen(buf)); // 写入到标准输出(文件描述符1)write(2, buf, strlen(buf)); // 写入到标准错误(文件描述符2)}return 0;
}
  • 文件描述符 0 对应 stdin

  • 文件描述符 1 对应 stdout

  • 文件描述符 2 对应 stderr

二、C 标准库文件操作模式

C 标准库的 fopen 函数支持多种文件操作模式,以下是一些常见的模式:

模式描述
r打开纯文本文件以只读方式,文件不能不存在。
r+打开纯文本文件用于读/写,文件不能不存在。
w打开纯文本文件用于写覆盖,若文件存在则清空,不存在则创建。
w+打开纯文本文件用于读/写覆盖,若文件存在则清空,不存在则创建。
a打开纯文本文件用于在文件尾部追加写入。
a+打开纯文本文件用于读/写,并在尾部追加新数据。

以下是一个使用 a+ 模式的示例:

#include <stdio.h>int main() 
{FILE *fp = fopen("myfile", "a+"); // 追加写入模式if (!fp) {printf("fopen error!\n");return 1;}const char *msg = "add new line\n";fwrite(msg, strlen(msg), 1, fp);fclose(fp);return 0;
}
  • a+ 模式表示以读写方式打开文件,并在文件尾部追加新数据。

三、系统调用文件操作

1. 文件的打开与描述符

以下是一个使用系统调用 open 打开文件的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main() 
{umask(0); // 设置文件权限掩码int fd = open("myfile", O_WRONLY | O_CREAT, 0644); // 打开或创建文件if (fd < 0) {perror("open");return 1;}const char *msg = "hello bit!\n";int len = strlen(msg);write(fd, msg, len); // 写入数据到文件close(fd); // 关闭文件return 0;
}
  • open 函数用于打开或创建文件。第二个参数是标志位,第三个参数是文件权限。

  • O_WRONLY | O_CREAT 表示以只写方式打开文件,如果文件不存在则创建。

  • 0644 是文件权限,表示文件所有者具有读写权限,组用户和其他用户具有只读权限。

  • write 函数将数据写入文件。第一个参数是文件描述符,第二个参数是数据的指针,第三个参数是数据的长度。

  • close 函数用于关闭文件描述符。

2. 文件的读取

以下是一个使用系统调用 read 读取文件的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main() 
{int fd = open("myfile", O_RDONLY); // 以只读模式打开文件if (fd < 0) {perror("open");return 1;}const char *msg = "hello bit!\n";char buf[1024];ssize_t s = read(fd, buf, strlen(msg)); // 读取文件数据if (s > 0) {printf("%s", buf);}close(fd);return 0;
}
  • read 函数从文件描述符中读取数据。第一个参数是文件描述符,第二个参数是数据的缓冲区,第三个参数是最大读取长度。

  • 返回值 s 表示实际读取的字节数。

3. 文件操作标志

系统调用 open 的第二个参数是标志位,以下是一些常见的标志位:

标志位描述
O_RDONLY以只读方式打开文件。
O_WRONLY以只写方式打开文件。
O_RDWR以读写方式打开文件。
O_CREAT如果文件不存在则创建。
O_APPEND以追加模式写入。
O_TRUNC如果文件存在,则清空文件内容。
O_EXCL如果使用 O_CREAT 标志时文件已存在,则失败。

4. 文件权限

系统调用 open 的第三个参数是文件权限,使用八进制表示。以下是一些常见的权限位:

权限位描述
0400所有者具有读权限。
0200所有者具有写权限。
0100所有者具有执行权限。
0040组用户具有读权限。
0020组用户具有写权限。
0010组用户具有执行权限。
0004其他用户具有读权限。
0002其他用户具有写权限。
0001其他用户具有执行权限。

5. 文件描述符

  • 文件描述符是一个小整数,由操作系统分配。

  • 程序默认拥有三个文件描述符:

    • 0:标准输入(stdin)。

    • 1:标准输出(stdout)。

    • 2:标准错误(stderr)。

以下是一个使用文件描述符输出数据的示例:

#include <unistd.h>
#include <string.h>int main() 
{char buf[] = "Hello World!\n";write(1, buf, strlen(buf)); // 使用文件描述符1(stdout)输出return 0;
}
  • write(1, buf, strlen(buf)) 表示将数据写入到标准输出流。

        文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针。本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件 。

四、C 标准库与系统调用的比较

1. 功能对比

功能C 标准库系统调用
文件打开fopenopen
文件读取freadread
文件写入fwritewrite
文件关闭fcloseclose
文件定位fseeklseek
标准输入输出stdin, stdout, stderr文件描述符0、1、2

2. 底层交互

  • C 标准库函数是封装好的函数,内部调用了系统调用。

    • 例如,fopen 是基于 open 实现的。

    • fwrite 是基于 write 实现的。

  • 系统调用直接与操作系统内核交互,执行效率更高,但使用更复杂。

3. 使用场景

  • C 标准库

    • 适合快速开发和处理简单的文件操作。

    • 提供了缓冲机制,数据处理更高效。

  • 系统调用

    • 适合对底层控制要求较高的场景,如设备驱动程序、高性能文件处理等。

    • 对文件描述符的直接操作,灵活性更高。

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

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

相关文章

【阮一峰】5.函数

函数 简介 函数的类型声明&#xff0c;需要在声明函数时&#xff0c;给出参数的类型和返回值的类型。 function hello(txt: string): void {console.log("hello " txt); }如果变量被赋值为一个函数&#xff0c;变量的类型有两种写法。 // 写法一 const hello f…

【R语言】主成分分析与因子分析

一、主成分分析 主成分分析&#xff08;Principal Component Analysis, PCA&#xff09;是一种常用的无监督数据降维技术&#xff0c;广泛应用于统计学、数据科学和机器学习等领域。它通过正交化线性变换将&#xff08;高维&#xff09;原始数据投影到一个新的坐标系&#xff…

pycharm画图程序如何一步一步的调试

1.设置合适的 Matplotlib 后端 在 PyCharm 中&#xff0c;有时需要手动指定 Matplotlib 后端。你可以尝试在脚本的最开始加入以下代码&#xff0c;强制使用 TkAgg 后端&#xff0c;这样可以保证图形更新的实时性&#xff1a; import matplotlib matplotlib.use(TkAgg) # 指定…

基于Java+Swing+Mysql实现旅游管理信息系统

基于JavaSwingMysql实现旅游管理信息系统 一、系统介绍二、功能展示1.登陆2.注册3.旅游信息查询4.查看游行团信息5.报名6、报名信息管理 三、数据库四、其它1.其他系统实现五.获取源码 一、系统介绍 用户&#xff1a;登陆、注册、旅游信息查询、查看游行团信息、报名 管理员&a…

Linux配置端口映射——其他机器可以访问

一般使用虚拟机都是NAT网络模式&#xff0c;但是这种模式的问题是&#xff1a;其他机器不能访问虚拟机 想让其他机器访问这个电脑上的虚拟机&#xff0c;需要做端口映射。 之后就可以使用finalshell连接 注意&#xff1a;如果要连接其他人的虚拟机&#xff0c;需要对方先关闭自…

快速部署deepseek

一、安装ollama 访问https://ollama.com/download 下载并安装对应系统的ollama。 Ollama 是一个开源工具&#xff0c;旨在帮助用户在本地机器上轻松运行和管理大型语言模型&#xff08;LLM&#xff09;。它提供了一个简单易用的命令行界面&#xff0c;可以下载、安装和运行各…

用Deepseek查询快证API-物流查询-实名认证-企业实名认证

快证API可能是一个提供多种验证和查询服务的平台&#xff0c;包括但不限于企业实名认证、短链接生成、手机号归属地查询、IP地址查询等。以下是根据搜索结果整理的关于快证API的相关信息&#xff1a; ‌企业实名认证API‌&#xff1a; 功能&#xff1a;通过与企业相关数据库进行…

基于指纹识别技术的考勤打卡设计与实现(论文+源码)

1 系统总体设计 本次基于指纹识别技术的考勤打卡系统的整体框图如图2.1所示&#xff0c;主控制模块选用单片机STC89C52&#xff0c;同时还包括AT24C02存储电路&#xff0c;指纹模块&#xff0c;LCD12864液晶&#xff0c;继电器&#xff0c;矩阵键盘等硬件电路。其中指纹模块和…

【云安全】云原生-K8S(四)安全问题分析

Kubernetes&#xff08;K8S&#xff09;因其强大的容器编排能力成为了云计算和微服务架构的首选&#xff0c;但同时也带来了复杂的安全挑战。本文将概述K8S的主要安全问题&#xff0c;帮助安全工程师理解潜在威胁&#xff0c;并采取相应的防护措施。 K8S 攻击面概览 下面两张…

基于JAVA毕业生信息招聘信息平台设计与实现

以往的毕业生信息招聘信息管理事务处理主要使用的是传统的人工管理方式&#xff0c;这种管理方式存在着管理效率低、操作流程繁琐、保密性差等缺点&#xff0c;长期的人工管理模式会产生大量的文本文件与文本数据&#xff0c;这对事务的查询、更新以及维护带来不少困难。随着互…

ES6模块化和CommonJs模块化区别

ES6模块化和CommonJs模块化区别 在JavaScript中&#xff0c;模块化是将代码拆分成独立的块&#xff0c;每个块可以独立封装和管理。ES6模块化和CommonJS是两种常见的模块化规范&#xff0c;它们在语法、加载方式和运行时特性上有显著差异。 语法差异 CommonJS模块使用requir…

DeepSeek自动化写作软件

DeepSeek写作软件的三大核心功能 对于内容创作者来说&#xff0c;写作不仅是表达思想的过程&#xff0c;更是一项需要投入大量时间和精力的任务。面对日益增长的内容需求&#xff0c;写作效率低下、内容质量不高等问题&#xff0c;常常让创作者感到焦虑。而 DeepSeek 写作软件…

深入解析 Flutter Bloc:从原理到实战

深入解析 Flutter Bloc&#xff1a;从原理到实战 Bloc&#xff08;Business Logic Component&#xff09;是 Flutter 中一个强大的状态管理工具&#xff0c;基于事件驱动的架构设计&#xff0c;适合管理复杂的业务逻辑和状态。Bloc 的核心理念是将业务逻辑与 UI 分离&#xff…

使用右侧值现象来处理一个word导入登记表的需求

需求也简单&#xff0c;导word文件用户登记表&#xff0c;有各部门的十几个版本&#xff08;为什么这么多&#xff1f;不知道&#xff09;。这里说下谈下我的一些代码做法&#xff1a; 需求分析&#xff1a; 如果能解决java字段和各项填的值怎么配对的问题&#xff0c;那么就…

Day48(补)【AI思考】-设计模式三大类型统一区分与记忆指南

文章目录 设计模式三大类型统一区分与记忆指南**一、创建型模式&#xff08;对象如何生&#xff1f;&#xff09;****二、结构型模式&#xff08;对象如何组&#xff1f;&#xff09;****三、行为型模式&#xff08;对象如何动&#xff1f;&#xff09;****1. 行为型类模式&…

Rook-ceph(1.92最新版)

安装前准备 #确认安装lvm2 yum install lvm2 -y #启用rbd模块 modprobe rbd cat > /etc/rc.sysinit << EOF #!/bin/bash for file in /etc/sysconfig/modules/*.modules do[ -x \$file ] && \$file done EOF cat > /etc/sysconfig/modules/rbd.modules &l…

Transformer技术报告:架构与原理

【深度学习】Transformer 技术报告&#xff1a;架构与原理 一、引言二、Transformer 的基本架构2.1 总体架构2.2 编码器&#xff08;Encoder&#xff09;2.3 解码器&#xff08;Decoder&#xff09;2.4 输入嵌入与位置编码 三、Transformer 的关键特性四、应用场景五、总结 一、…

电子制造企业数字化转型实战:基于Odoo构建MES平台的深度解决方案

作者背景 拥有8年乙方项目经理经验、8年甲方信息化管理经验&#xff0c;主导过12个Odoo制造业项目落地&#xff0c;服务客户涵盖消费电子、汽车电子、工业设备等领域。本文基于华东某电子企业&#xff08;以下简称"A公司"&#xff09;的实战案例&#xff0c;解析行业…

【实战】用飞书多维表格+AI DeepSeeker做股票量价分析

用2万元起步资金&#xff0c;进行A股实战模拟。&#xff08;量化分析无法知晓 消息面的事宜&#xff0c;是一个不足&#xff0c;但是可以代替 哪些一般水平的 股票分析师&#xff09; https://zk4wn8rhv2.feishu.cn/base/OABmbEBa4a4zgOsw5JlcrfIPnzh?tabletblMK2bDhPW5Am9b&a…

计算四个锚点TOA定位中GDOP的详细步骤和MATLAB例程

该MATLAB代码演示了在三维空间中,使用四个锚点的TOA(到达时间)定位技术计算几何精度衰减因子(GDOP)的过程。如需帮助,或有导航、定位滤波相关的代码定制需求,请联系作者 文章目录 DOP计算原理MATLAB例程运行结果示例关键点说明扩展方向另有文章: 多锚点Wi-Fi定位和基站…