IO / 标准IO 和 文件IO 的总结

我将标准IO和文件IO有关概念、api总结在一张表格了,方便查找使用

标准IO

文件IO

概念

使用库函数实现,将内核提供的IO函数接口进行了再次封装,因为有缓冲区,所以效率比文件IO高

对文件进行操作,使用的是文件指针来进行

标准IO = 文件IO + 缓冲区

使用系统调用,内核提供的函数,每次进行IO操作,进程都会从用户空间向内核空间进行一次切换

文件IO直接进行系统调用,用文件描述符进行对文件操作

文件标识

FILE结构体

  • FILE结构体时stdio.h头文件中已经定义的一个关于文件操作的结构体类型
  • 后期关于标准IO的文件相关的操作,只需基于该结构体对象即可
  • 使用fopen函数成功打开一个文件后,就会返回该文件对应的FILE类型的地址
  • FILE结构体的原型

struct _IO_FILE { char* _IO_buf_base; char* _IO_buf_end; int _fileno; } typedef struct _IO_FILE FILE;

  • 特殊的文件指针: 当运行一个进程时,系统自动打开三个文件FILE指针,表示用于对终端文件的操作
    • stdin:标准输入流指针
    • stdout:标准输出流指针
    • stderr:标准错误流指针

文件描述符

  • 对于标准IO,对文件进行操作,使用的是文件指针来进行,其中文件指针结构体中,除了包含缓冲区的相关信息外,还提供一个整数用于进行系统调用,这个整数就是文件描述符
  • 对于文件IO而言,由于直接进行系统调用,所以,依赖的就是文件描述符进行对文件操作
  • 所谓文件描述符,是使用open函数后,打开的一个用于对指定文件进行操作的一个整数
  • 一个进程中文件描述符的个数是有限的,默认为1024个[0--1023],可以通过ulimit -a查看
  • 文件描述符的使用原则:最小未分配原则
  • 当一个进程启动后,系统会默认打开三个文件描述符
    • 0:stdin->_fileno -->标准输入文件描述符
    • 1:stdout->_fileno -->标准输出文件描述符
    • 2:stderr->_fileno -->标准出错文件描述符

打开文件

fopen

#include

FILE *fopen(const char *pathname, const char *mode);

  • 功能:以指定的形式打开一个指定的文件,并返回该文件的文件地址
  • 参数1:要打开的文件路径,是一个字符串
  • 参数2:文件的打开模式,也是一个字符串,必须以以下字母开头
    • r, r+, w, w+, a, a+
  • 返回值:成功返回打开文件的文件指针,失败返回NULL,并置位错误码

open

#include

#include

#include

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

  • 功能:打开或创建一个指定的文件
  • 参数1:要打开的文件路径
  • 参数2:打开标志
    • 以下三个模式中必须选择一个:
      • O_RDONLY(只读)
      • O_WRONLY(只写)
      • O_RDWR(读写).
    • 下面常用的打开标志
      • O_CREAT:创建,如果第二个参数中有该值,则第三个参数必须要写,如果没有,则第三个参数可以省略
      • O_TRUNC:清空文件内容
      • O_APPEND:追加形式打开
      • O_EXCL:确保创建一个新文件,如果文件已经存在,则open函数报错,错误码为EEXIST
      • O_NONBLOCK:以非阻塞的形式打开文件
      • 多个标识位使用位或隔开:

关闭文件

fclose

#include

int fclose(FILE *stream);

  • 功能:关闭指定的文件,关闭前刷新该文件指针对应的缓冲区,并关闭底层的文件描述符
  • 参数:文件指针,使用fopen函数返回的文件指针
  • 返回值:成功返回0,失败返回EOF(-1), 并置位错误码

close

#include

int close(int fd);

  • 功能:释放一个文件描述符关联的文件,后期可以用于别的文件
  • 参数:要释放的文件描述符
  • 返回值:成功返回0,失败返回-1并置位错误码

单字符输入

fgetc

#include

int fputc(int c, FILE *stream);

  • 功能:将给定的字符,写入指定的文件中
  • 参数1:要输出的字符
  • 参数2:指定的文件指针
  • 返回值:成功返回写入的字符的unsigned char数据,失败返回EOF

单字符输出

fputc

#include

int fputc(int c, FILE *stream);

  • 功能:将给定的字符,写入指定的文件中
  • 参数1:要输出的字符
  • 参数2:指定的文件指针
  • 返回值:成功返回写入的字符的unsigned char数据,失败返回EOF

字符串读

fgets

#include

char *fgets(char *s, int size, FILE *stream);

  • 功能:从指定的文件中读取最多size-1个字符,到s字符数组中
  • 参数1:字符串容器
  • 参数2:读取的大小,最多读取size-1个字符,字符串的最后会加上一个结束标志'\0'
  • 参数3:文件指针
  • 返回值:成功返回读取的字符串起始地址,失败返回NULL
  • 注意:在读取数据时,如果遇到'\n'会结束一次读取,并且将'\n'也放入字符串中,后面加个'\0'

字符串写

fputs

#include

int fputs(const char *s, FILE *stream);

  • 功能:将指定的字符串写入到指定的文件中去
  • 参数1:要写入的字符串起始地址
  • 参数2:要写入的文件指针
  • 返回值:成功返回输出的字符个数,失败返回EOF

格式化读

fscanf

int fscanf(FILE *stream, const char *format, ...);

功能:从文件中按给定的格式读取一些数据

  • 参数1:文件指针
  • 参数2:格式串
  • 参数3:不定参数,个数根据参数2中的格式控制符而定
  • 返回值:成功返回读取数据的项数,参数2中格式控制符的个数,失败返回小于参数2中格式控制符的个数

格式化写

fprintf

int fprintf(FILE *stream, const char *format, ...);

  • 功能:向文件中输出一个格式串
  • 参数1:文件指针
  • 参数2:格式串
  • 参数3:不定参数,个数根据参数2中的格式控制符而定
  • 返回值:成功返回输出的字符个数,失败返回一个负数

模块化读

fread

#include

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

  • 功能:从文件中读取nmemb项数据,每一项大小为size,将数据放入ptr指向的起始地址中
  • 参数1:读取数据的容器起始地址
  • 参数2:每一项的大小
  • 参数3:总的项数
  • 参数4:文件指针
  • 返回值:成功返回写入的项数,失败返回一个小于项数的值
  • 注意:fread是不区分文件结束或者文件读取错误的,需要使用feof和ferror来进行区分

read

#include

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

  • 功能:向指定文件中写入数据,起始地址为buf,一共写入count给字节
  • 参数1:要写入文件的文件描述符
  • 参数2:要写入数据的起始地址
  • 参数3:写入数据的大小
  • 返回值:成功返回读取字符的个数,失败返回-1并置位错误码

模块化写

fwrite

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

  • 功能:将ptr指向的内容,写入到文件中去
  • 参数1:要写入内容的起始地址,void*表示能够写入任意类型的数据
  • 参数2:每一项的大小
  • 参数3:总项数
  • 参数4:文件指针
  • 返回值:成功返回写入的项数,失败返回一个小于项数的值

write

#include

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

  • 功能:向指定的文件中写入数据,起始地址为buf,一共写入count个字节
  • 参数1:要写入文件的文件描述符
  • 参数2:要写入数据的起始地址
  • 参数3:写入数据的大小
  • 返回值:成功返回写入数据的个数,失败返回-1并置位错误码

光标控制

fseek

#include

int fseek(FILE *stream, long offset, int whence);

  • 功能:移动光标的位置
  • 参数1:要移动光标的文件指针
  • 参数2:偏移量
  • >0:向后偏移
  • =0:不偏移
  • 参数3:偏移起始位置
    • SEEK_SET:文件开头位置
    • SEEK_CUR:光标当前位置
    • SEEK_END:文件结尾位置
  • 返回值:成功返回0,失败返回-1并置位错误码

lseek

#include

#include

off_t lseek(int fd, off_t offset, int whence);

  • 功能:将文件描述符对应的文件光标进行偏移
  • 参数1:文件描述符
  • 参数2:偏移量,以字节为单位
    • >0:向后偏移
    • =0:不偏移
  • 参数3:起始位置
    • SEEK_SET:从文件开头
    • SEEK_CUR:文件当前位置
    • SEEK_END:文件结尾位置
  • 返回值:成功返回光标现在所在位置,失败返回-1并置位错误码 (等价于:fseek+ftell)

光标控制

ftell

long ftell(FILE *stream);

功能:返回光标现在所在位置到开头的总字节数

参数:文件指针

返回值:当前文件指针的光标到开头位置的字节总数

eg:

fseek(fp, 0, SEEK_END); //定位在结尾

ftell(fp); //返回的结果就是文件的大小

光标控制

rewind

void rewind(FILE *stream);

  • 功能:将光标重新定位在开头,等价于fseek(fp, 0, SEEK_SET);
  • 参数:文件指针
  • 返回值:无


目录:目录 / 学习笔记快速链接

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

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

相关文章

网络推理之深度学习推理框架

如何选择深度学习推理框架? PyTorch vs LibTorch:网络推理速度谁更快? 高质量C进阶[2]:如何让线性代数加速1000倍? TensorRT: ONNX:

微服务--07--Sentienl中使用的限流算法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 Sentienl中使用的限流算法1、计数器固定窗口算法2、计数器滑动窗口算法----(默认)3、漏桶算法----(排队等待)4、令牌…

node.js 启一个前端代理服务,代码直接改一改拿来用

文章目录 前言一、分析技术二、操作步骤2.1、下载依赖2.2、创建一个 serve.js 文件2.3、js 文件中写入以下代码 三、运行: node serve四、结果展示五、总结六、感谢 前言 有时候我们需要做一些基础的页面时,在研发过程中需要代理调用接口避免浏览器跨域…

AI全栈大模型工程师(二十六)如何选择 GPU 和云服务厂商

💡 这节课会带给你 如何选择 GPU 和云服务厂商,追求最高性价比 如何部署自己 fine-tune 的模型,向业务提供高可用推理服务 如何控制内容安全,做好算法备案,确保合规 开始上课! 硬件选型 当我们为模型训练及…

电子学会C/C++编程等级考试2022年12月(五级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:漫漫回国路 2020年5月,国际航班机票难求。一位在美国华盛顿的中国留学生,因为一些原因必须在本周内回到北京。现在已知各个机场之间的航班情况,求问他回不回得来(不考虑转机次数和机票价格)。 时间限制:1000 内存限制:655…

golang 基于数组、切片、链表实现队列

数组 package mainimport ("errors""fmt" )func main() {// 创建一个简单队列// 如果head tail 队列空// 如果tail len(array) - 1// 整体做迁移 如果head 0 队列满stack1 : createQueue[int]()err : stack1.push(1)// 处理错误 后面的就不处理了if er…

Ajax原理以及优缺点

Ajax原理 1.Ajax的原理简单来说是在用户和服务器之间加了—个中间层(AJAX引擎),通过XmlHttpRequest对象来向服务器发异步请求, 2.从服务器获得数据,然后用javascript来操作DOM而更新页面。使用户操作与服务器响应异步化。 3.这其中最关键的一…

Java----冒泡排序、选择排序、插入排序、快速排序、堆排序

int[] arr {4, 2, 7, 1, 5, 9, 3, 6, 8}; 冒泡排序 for(int i 0; i < arr.length-1; i) //外循环是控制排序的次数n-1, 每次循环结束确定一个最大值{for(int j 0; j < arr.length - 1 - i; j) // 内循环是第i次循环中比较的次数n-i{if(arr[j] > arr[j1]){//前面一…

LeetCode-23. 合并 K 个升序链表

问题分析 先建立一个小顶堆将每一路的最小元素都加入小顶堆&#xff0c;此时堆顶元素就是全局的最小值将堆顶元素弹出。若堆顶元素所在的数组不为空&#xff0c;则将下一元素加入堆中重复2、3操作&#xff0c;直到所有数据都读取完毕将堆内元素按顺序读出&#xff0c;并清空堆…

双系统安装显卡驱动

安装步骤 更新系统: 在安装任何新软件之前&#xff0c;最好先更新系统&#xff0c;以确保所有依赖都是最新的。打开终端&#xff08;Terminal&#xff09;并运行以下命令&#xff1a; sudo apt update sudo apt upgrade关闭Nouveau驱动: Nouveau是Nvidia显卡的开源驱动&#xf…

Linux系统使用ESP8266开发板(CP2102)

连接ESP8266开发板到电脑 虚拟机选择开发板硬件连接 查看USB连接情况: lsusb 授权USB接口访问 成功连接 编译项目 上传到开发板 成功提供WIFI热点服务

跳跃游戏 + 45. 跳跃游戏 II

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输…

动态SQL学习及使用场景(简略)

假设我们有一个商品表&#xff0c;包含id、name、price和category四个字段。现在需要实现修改商品价格的功能&#xff0c;我们可以使用动态SQL实现。 首先&#xff0c;我们需要构造一个SQL语句&#xff0c;根据用户提供的参数来动态生成&#xff0c;具体实现如下&#xff1a; …

三、Shell 环境

一、Linux 系统分类 在 Linux 中&#xff0c;常见的 Shell 有以下几种&#xff1a; Bourne Shell&#xff08;sh&#xff09;&#xff1a;最早的 Shell&#xff0c;由 Stephen Bourne 开发。它是大多数其他 Shell 的基础。Bourne Again Shell&#xff08;bash&#xff09;&am…

Tomcat指定jdk启动

要在Tomcat中指定使用特定的JDK启动&#xff0c;可以按照以下步骤进行操作&#xff1a; 确保你已经安装了所需的JDK&#xff0c;并且知道其安装路径。 打开Tomcat的安装目录&#xff0c;在bin目录下找到catalina.bat&#xff08;Windows&#xff09;或catalina.sh&#xff08;…

thinkphp6入门(13)-- 一对多关联模型

定义一对一关联&#xff0c;例如&#xff0c;一个用户都有多个工作经历。 一、两表 1.用户表:user 2.工作经验表&#xff1a;work_experience user表的id关联work_experience表的user_id。 注意看&#xff0c;user_id1的有2条工作经验 二、数据模型 主表模型&#xff1a;…

2023.12.6 关于flask中的route、render_template、redirect的关系问题

2023.12.6 关于flask中的route、render_template、redirect的关系问题 之前对于route、render_template、redirect三者的关系还有一些模糊&#xff0c;测试了一个案例后就比较清晰了&#xff0c;简单来说就是路径、模板和重定向&#xff0c;三者相对独立&#xff0c;只是一般命…

我的创作纪念日-第四年

机缘 不知不觉&#xff0c;CSDN 写博客已经四年了&#xff0c;也伴随了我读研读博的绝大多数时间。最多的时候&#xff0c;还是想记录下自己所走过的路程吧&#xff0c;然后留给后人一点经验借鉴。 实战项目中的经验分享   应该只分享过一篇博文&#xff1a;基于Jetson nan…

如何在 1 天内将网站打造为手机app

为您的网站提供移动应用程序的重要性怎么强调都不为过。随着用户越来越依赖智能手机和平板电脑进行在线活动&#xff0c;将您的网站转变为移动手机app可以显着增强用户体验、提高参与度并扩大您的在线影响力。在这篇博客中&#xff0c;我们将探讨如何快速有效地将网站制作成移动…

【Let‘s Encrypt SSL】使用 acme.sh 给 Nginx 安装 Let’s Encrypt 提供的免费 SSL 证书

安装acme.sh 安装 acme.sh 并设置邮箱用来接受重要通知&#xff0c;如证书快过期未更新通知 curl https://get.acme.sh | sh -s emailmyexample.com执行命令后几秒就安装好了&#xff0c;如果半天没有反应请 CtrlC 后重新执行命令。acme.sh 安装在 ~/.acme.sh 目录下&#xf…