IO入门day1

news2024/12/29 13:13:12

课程分为三部分:IO文件-动态库、静态库制作,进程(本地进程间通信),线程(线程通信)

特点:学习大量的函数接口调用-函数名及功能、man手册查看参数

一、IO介绍

1、概念

对文件的输入输出。I :input  O:output

读文件:将文件中的内容读到内存中进行处理

写文件:将内存中的内容写到文件中

文件是存放到磁盘空间上的,掉电文件不丢失

2、linux文件类型:

b(块设备文件)

c(字符设备文件)

d(目录文件)

-(普通文件)

l(链接文件)

s(套接字文件)网络编程

p(管道文件)

二、文件IO和标准IO区别

总结:

   标准IO:是c库提供的输入输出函数接口。不同的操作系统都可以使用,只要有库就行。是在系统调用之前做了一个二次封装,间接进行了系统调用。

          文件IO:内核向上提供的输出输出函数接口,叫做系统调用函数接口。基于内核,内核不同,系统调用函数接口不同,文件IO不同操作系统函数接口不通用。

fread-标准IO的函数接口
{
    if(是linux)
    {
        //调用linux的系统调用函数接口
        read();
    }
    else if(是windows)
    {
         _read();
    }
    else if(是mac)
    {
        Read();
    }
}
标准IO在系统调用之前做二次封装增加缓存机制 ,减少了系统调用次数,提高效率。

  • 三、标准IO

 1.标准I/O

    标准IO是指在C库中提供的一组专门用于输入输出的函数

    标准I/O由ANSI C标准定义不仅在UNIX系统,在很多操作系统上都实现了标准I/O

    标准I/O通过缓冲机制减少系统调用,实现更高效率

 标准I/O库的所有操作都是围绕流(stream)来进行的,在标准I/O中,流用FILE *来描述。

    标准IO默认打开了三个流:stdin、stdout、stderr-->标准输入、标准输出、标准出错 

 2. 文件 I/O   man 2  

是有linux内核提供的接口函数

这些操作往往都会涉及到 对硬件的操作,

磁盘运行速度比较慢,因此要减少磁盘的

读写次数,没有缓冲机制。

增加每次续写的量 ,也就是减少 

read write 函数的调用次数。

四、流

 定义:所有的I/O操作仅是简单的从程序移进或者移出,这种字节流,就称为流。

   分类:文本流/二进制流。

  流指针:FILE *

每个被打开的文件都在内存中开辟一个区域,

用来存放文件的有关信息,这些信息是保存在一个

结构体类型的变量中,该结构体类型是由系统定义的,

取名为FILE。 

查看结构体:FILE       追踪软件ctags

    vi   -t    FILE  

typedef struct  _IO_FILE FILE; 

   ctrl  ’]‘  :追踪

   ctrl  ’t‘ :返回:

用结束地址减去起始地址可以得到缓存区大小:

  char* _IO_buf_base;   /* 缓存区的起始地址 */

          char* _IO_buf_end;    /* 缓存器的结束后地址 */

围绕“流”进行操作,“流”用FILE*表示。 

  • FILE是数据类型(结构体),FILE*结构体指针。
  • 文件内部有文件指针,文件用文件指针操作,流只是起到了一个媒介的作用,封装原来的接口等,开辟缓冲区,减少系统调用。
  • 索引使用:1.vi -t要查找的内容 (查找宏,数据类型等)

输入前面序号,回车

  1. 继续追踪

将光标定位到要追踪的内容上,ctrl+] (右中括号)

回退:ctrl+t

3)标准IO默认打开了三个流,stdin(标准输入)、stdout(标准输出)、stderr(标准错误)

三个流是结构体指针变量。

4)标准IO一般只用于操作普通文件

五、标准I/O常见函数

1. fopen / fclose  打开文件 关闭文件 

2. fgetc / fputc   读一个字符/写一个字符

3. fgets / fputs   读一个字符串/写一个字符串

4. fwrite/ fread   读写一个二进制文件

5. fseek     移动文件指针(光标)函数

  • 六、缓冲区分类

注意:缓存区是在使用的时候才会开辟

   1.全缓存  -->fopen打开的文件都是全缓存

   刷新全缓存:

1.程序正常退出

  2.fflush强制刷新缓存

  3.遇到return (main)

  4.exit退出进程

  5.关闭fclose流指针

  6.缓存区满

   2.行缓存  -->基于终端:stdin\stdout

     刷新缓存区:

  1.'\n'刷新

  2.程序正常退出

  3.fflush强制刷新缓存

  4.遇到return (main)

  5.exit退出进程

  6.关闭fclose流指针

7.缓存区满

 注意:当遇到阻塞输入函数时,输出缓存区会刷新       

   3.不缓存:  stderr  

行缓存区大小计算:

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

int main(int argc, char const *argv[])
{
 //计算行缓存的大小   
   /*  for(int i=1;i<300;i++)//256*4=1024 = 1KB
    {
      printf("%4d",i);
    }*///缓存区满计算
  //缓存区首尾地址之差
    printf("hello world.");//缓存区使用时开辟
    printf("size:%d\n",stdout->_IO_buf_end-stdout->_IO_buf_base);
    while(1);
    return 0;
}

fflush函数:

查看错误码  vi -t EEXIST

#include <stdio.h>
int fflush(FILE *stream);
功能:刷新缓存区
参数:
    stream:流  (NULL:刷新所有流)
返回值:成功 0
失败:返回错误码 EOF(-1),更新errno。

七、缓冲机制

1)全缓冲:跟文件相关

刷新条件:

程序正常结束

缓冲区满刷新

强制刷新:fflush

2)行缓冲:跟终端相关

刷新条件:

\n

程序正常结束

缓冲区满刷新

强制刷新:fflush

#include <stdio.h>

int main(int argc, char const *argv[])
{
    //1.\n刷新缓冲区
    // printf("hello world\n");

    // while (1)
    //     ;
    //2.程序正常退出
    // printf("hello world");

    // while (1)
    //     ;//不让程序结束
    //3.缓冲区满刷新
    //有大小,当将缓冲区写满数据时,
    //再继续向缓冲区中写数据,
    //会将原来缓冲区中满了的数据全部拿出来,打印到终端
    //新写的数据,可以继续向里面写
    //测试缓冲区大小 kb 1kb=1024byte 1b=8bit
    //缓冲区大小1kb
    //方法一:
    // for(int i=0;i<300;i++)
    // {
    //     printf("%4d",i);
    // }
    // while(1);
    //方法二:
    //缓冲区的结束地址-起始地址=缓冲区大小
    // printf("hello"); //开辟缓冲区
    // printf("%d\n", stdout->_IO_buf_end - stdout->_IO_buf_base);
    // 4.强制刷新
    printf("hello");
    //fflush(stdout);//强制刷新
    fflush(NULL);//强制刷新所有的输出缓存
    while (1)
        ;
    return 0;
}

return 是函数的正常结束

ctrl +c是函数的不正常结束

3)不缓冲:没有缓冲区,标准错误

scanf--》标准输入缓冲区---》终端输入

标准输入缓冲区有内容 不进入终端输入

printf--》标准输出缓冲区---》终端

  • 八、标准IO函数接口

1fopen  freopen打开文件

1)fopen 打开文件

FILE *fopen(const char *path, const char *mode)
功能:打开文件
参数:
    path:打开的文件路径
    mode:打开的方式
        r:只读,当文件不存在时报错,文件指针定位到文件开头
        r+:可读可写,当文件不存在时报错,文件指针定位到文件开头
        w:只写,文件不存在创建,存在清空文件,文件指针定位到文件开头
        w+:可读可写,文件不存在创建,存在清空文件,文件指针定位到文件开头
        a:追加(在末尾写),文件不存在创建,存在追加,文件指针定位到文件末尾
        a+:读和追加,文件不存在创建,存在追加,读文件指针定位到文件开头,
            写文件流定位到文件末尾
注:当a的方式打开文件时,写只能在末尾进行追加,定位操作是无法改变写的位置,但是可以改变读的位置
返回值:成功:得到一个文件流指针
      失败:NULL,并且会设置错误码

a+:初始读指针在文件开始位置,写指针在文件结束位置,如果只调用读指针,那么读指针从刚开始位置后移,一旦调用写指针,读写指针合二为一,读指针去到写指针的位置

测试:一个任务中最多能打开多少个文件?(一个文件是可以被重复打开)1024个;

  1. 2、获取错误信息 perror 

2.1查看错误码  vi -t EEXIST

void perror(const char *s);
功能:根据errno值获取错误信息,将信息输出到终端
参数:
    s:错误信息的内容
返回值:无

  1. 3、关闭文件:fclose

int fclose(FILE* stream);
功能:关闭文件
参数:stream:文件流
成功:返回0
失败:返回-1,更新erron

4、读写操作

1)fgetc:每次读一个字符

int  fgetc(FILE * stream)
功能:从文件中读取一个字符
参数:stream:文件流
返回值:成功:读到的字符ASCII码
      失败或读到文件末尾:EOF(-1)

2)fputc:每次写一个字符

int fputc(int c, FILE * stream)
功能:向文件中写入一个字符
参数:c:要写的字符
   stream:文件流
返回值:成功:写的字符的ASCII
      失败:EOF-1

练习1、用fgetc和fputc完成cp功能

练习2、测试全缓存大小

3)fprintf定向输出到文件中

int fprintf(FILE *stream, const char *format, ...);
    功能:向指定的文件以指定的格数写入数据
	  参数: stream :流指针
	    format:指定格式
		...:多个参数
	返回值:输出字符个数
	 失败返回:EOF


4)fgets:

char * fgets(char *s,  int size,  FILE * stream);
功能:从文件中每次读取一行字符串
参数:s:存放字符串的地址
         size:一次读取的字符个数         
         stream:文件流
 返回值:成功:s的地址
       失败或读到文件末尾:NULL
特性:每次实际读取的字符个数为size-1个,会在末尾自动添加\0
       每次读一行,遇到\n后不再继续,读下一行

5)fputs

 int fputs(const char *s, FILE *stream);
   功能:向指定文件中输入一串字符
   参数:
         s:输入字符串的首地址
		 stream:文件流指针
	返回值:成功返回输出字符个数
	失败返回EOF

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

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

相关文章

Vue3中使用富文本编辑器

在vue3中我们可以使用wangeditor/editor、wangeditor/editor-for-vue来实现其功能 npm地址&#xff1a;https://www.npmjs.com/package/wangeditor/editor-for-vue/v/5.1.12?activeTabreadme 官网&#xff1a;Editor 1. 安装 pnpm add wangeditor/editor # 或者 npm inst…

ESRI ArcGIS Desktop 10.8.2图文安装教程及下载

ArcGIS 是由美国著名的地理信息系统公司 Esri 开发的一款地理信息系统软件&#xff0c;它是目前全球最流行的 GIS 软件之一。ArcGIS 提供了图形化用户界面和数据分析工具&#xff0c;可以帮助用户管理、分析和可视化各种空间数据。ArcGIS Desktop是一个完整的桌面GIS软件套件&a…

2023“龙芯杯”信创攻防赛 | 赛宁网安技术支持

2023年10月19日&#xff0c;为深入贯彻国家网络强国战略思想&#xff0c;宣传国家网络安全顶层设计&#xff0c;落实《网络安全法》《数据安全法》等法律法规。由大学生网络安全尖锋训练营主办&#xff0c;龙芯中科技术股份有限公司承办&#xff0c;山石网科通信技术股份有限公…

解决XXLJOB重复执行问题--Redis加锁+注解+AOP

基于Redis加锁注解AOP解决JOB重复执行问题 现象解决方案自定义注解定义AOP策略redis 加锁实践 现象 线上xxljob有时候会遇到同一个任务在调度的时候重复执行&#xff0c;如下图&#xff1a; 线上JOB服务运行了2个实例&#xff0c;有时候会重复调度到同一个实例&#xff0c;有…

【标准化封装 SOT系列 】 B SOT-223

SOT-223 pin 间距 2.3mm 名称pin 数厂家 body DE矩形 (mm)SOT-2234ADI – LTC196 . 6.3/6.71*3.3/3.71

基于广义正态分布优化的BP神经网络(分类应用) - 附代码

基于广义正态分布优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于广义正态分布优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.广义正态分布优化BP神经网络3.1 BP神经网络参数设置3.2 广义正态分布算…

接口测试 Jmeter 接口测试 —— 请求 Headers 与传参方式

一、 背景&#xff1a; 在使用 Jmeter 进行接口测试时&#xff0c;有些小伙伴不知道 Headers 和请求参数 (Parameters&#xff0c;Body Data) 的联系&#xff0c;本文主要讲 Content-Type 为 application/x-www-form-urlencoded 和 application/json 的场景。 1、使用 Parame…

Cesium Vue(七)— GEOJSON数据展示

1. GeoJSON GeoJSON 是一种用于对各种地理数据结构进行编码的格式。 简而言之&#xff0c;GeoJSON为你提供了一种简单的格式来表示简单的地理特征以及它们的非空间属性。 结构&#xff1a; {"type": "Feature","geometry": {"type"…

交叉熵(crossentropy)损失

1 神经网络分类问题 分类问题&#xff0c;通常分为二分类问题与多分类问题&#xff08;大于2类&#xff09;。 2 二分类问题 2.1 网络设计 神经网络的最后一层&#xff08;输出层&#xff09;&#xff0c;为一个神经元&#xff0c;使用激活函数sigmoid。 tf.keras.layers.…

如何测试WordPress能否成功发送邮件

如果你的WordPress网站没有连接到SMTP服务器&#xff0c;就发不了邮件。 修改管理员密码&#xff0c;发不了邮件。 用户提交表单&#xff0c;你收不到邮件提醒。 确定真的需要配置SMTP 有的服务器在一键安装WordPress的时候&#xff0c;已经帮你配置好了&#xff08;比如Sit…

windos默认输入法开机无法使用,需要手动执行ctfmon.exe

windos默认输入法开机无法使用&#xff0c;需要手动执行ctfmon.exe 系统&#xff1a;win10专业版 第一种方法 以管理员身份运行cmd 执行 sfc /scannow 1.右键点击此电脑&#xff0c;点击管理&#xff0c;打开如图所示服务选项卡&#xff0c;找到如图所示服务点击启动&#…

数据结构与算法(十):动态规划与贪心算法

参考引用 Hello 算法 Github&#xff1a;hello-algo 1. 动态规划算法 动态规划将一个问题分解为一系列更小的子问题&#xff0c;并通过存储子问题的解来避免重复计算&#xff0c;从而大幅提升时间效率 问题&#xff1a;给定一个共有 n 阶的楼梯&#xff0c;你每步可以上 1 阶或…

Django和jQuery,实现Ajax表格数据分页展示

1.需求描述 当存在重新请求接口才能返回数据的功能时&#xff0c;若页面的内容很长&#xff0c;每次点击一个功能&#xff0c;页面又回到了顶部&#xff0c;对于用户的体验感不太友好&#xff0c;我们希望当用户点击这类的功能时&#xff0c;能直接加载到数据&#xff0c;请求…

C#,数值计算——分类与推理Phylagglomnode的计算方法与源程序

1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Phylagglomnode { public int mo { get; set; } public int ldau { get; set; } public int rdau { get; set; } public …

# 用acme.sh申请证书(含泛域名)

用acme.sh申请证书&#xff08;含泛域名&#xff09; 文章目录 用acme.sh申请证书&#xff08;含泛域名&#xff09;1 申请证书&#xff1a;1.1 使用dns api方式申请证书&#xff08;以阿里云dns为例&#xff09;1.2 附加&#xff1a;也可以用其他方式申请证书 2 续签证书&…

跨域方案的抉择

前言 遇到跨域问题的时候&#xff0c;到底是使用CORS来解决&#xff0c;还是使用代理呢&#xff1f; 判断依据不是技术层面&#xff0c;而是你的生产环境。 首先要关注的是生产环境里面到底是一种什么样的情况&#xff0c;到底有没有跨域&#xff0c;然后根据生产环境的情况&a…

yjs demo: 多人在线协作画板

基于 yjs 实现实时在线多人协作的绘画功能 支持多客户端实时共享编辑自动同步&#xff0c;离线支持自动合并&#xff0c;自动冲突处理 1. 客户端代码&#xff08;基于Vue3&#xff09; 实现绘画功能 <template><div style"{width: 100vw; height: 100vh; over…

Matlab遗传算法工具箱——一个例子搞懂遗传算法

解决问题 我们一般使用遗传算法是用来处理最优解问题的&#xff0c;下面是一个最优解问题的例子 打开遗传算法工具箱 ①在Matlab界面找到应用程序选项&#xff0c;点击应用程序(英文版的Matlab可以点击App选项) ②找到Optimization工具箱&#xff0c;点击打开 创建所需要…

[SQL开发笔记]INSERT INTO 语句:将新记录插入到数据库表中

目前&#xff0c;向数据库插入数据是数据管理的重要环节&#xff0c;它可以将数据长期保存、共享访问、保证数据的完整性和安全性&#xff0c;同时也是进行数据检索和分析的基础。其中&#xff0c;INSERT INTO 语句是SQL&#xff08;结构化查询语言&#xff09;中用于向数据库表…

【王道代码】【2.3链表】d1

关键字&#xff1a; 递归删除x&#xff1b;删除所有x&#xff1b;递归反向输出&#xff1b;删除最小结点&#xff08;2组指针&#xff09;&#xff1b;原地逆置&#xff1b;使递增有序