【1】什么是IO

#include <stdio.h>

input:输入,从外部存储设备输入到内存中

output: 输出,从内存输出到外部存储设备。

> 存储设备:
>
> ​    外部存储设备,硬盘
>
> ​    内存:SDROM DDR4;

总结:数据从外部存储设备到内存,内存到外部存储设备的流动

【2】IO分类

1.文件IO

文件IO:由操作系统提供,与操作系统绑定,又称之为系统调用

|      | windows    | linux |
| ---- | ---------- | ----- |
|      | file_read  | read  |
|      | file_write | write |

注意:

1. 文件IO的复用性,可移植性较低
2. 文件IO涉及到cpu从用户空间切换到内核空间,C代码调用汇编语言等等操作,是一个**耗时的操作**,所以应该尽量减少文件IO的使用。

2.标准IO

标准IO:根据ANSI标准对文件IO进行二次封装,
printf();
if(OS == windows)
{
    file_write;
}
else if(OS == Linux)
{
     write;
}

作用:

1. 提高代码的复用性和可移植性;

2. 提高了输入输出的效率;

设置了一个缓冲区,缓冲区满或者满足一定条件后,调用文件IO,陷入内核,由内核完成对文件的输入输出,大大减少了对文件IO的使用。

2. 标准IO

【1】流和流指针

流(stream):将数据一个一个移入或者移出缓冲区的形式,称之为字节流;

流指针(FILE*):每打开一个文件,都会在内存中申请一片空间(缓冲区);

​                            管理这片空间的变量都存储在FILE结构体中,FILE结构体由系统定义好了,我们使用即可;

1. FILE结构体成员

> vi -t指令         查找系统定义好的数据类型 和 变量 宏
>
> 1)sudo apt-get install ctags
>
> 2)cd  /usr/include/     如果只需要查看标准库中的内容
>
> 3)sudo ctags -R
>
> 4)在家目录的.vimrc中添加 set tags+=/usr/include/tags
>
> 追代码:
>
> ​        ctrl + 鼠标左键
>
> ​        或者 左键选中要追的代码 ctrl + ]
>
> ```c
> $ vi -t FILE
>     typedef struct _IO_FILE FILE; 
> ctrl + 鼠标左键点击 _IO_FILE
> ```

```c
struct _IO_FILE {
  char* _IO_buf_base;   /* Start of reserve area. */     缓冲区的起始地址
  char* _IO_buf_end;    /* End of reserve area. */         缓冲区的结束地址

int _fileno;         文件描述符
}
```

2. 标准输入输出流

在main函数启动之前。系统会默认打开三个流指针;

```
stdin     标准输入流指针          从终端读取数据
stdout     标准输出流指针             将数据输出到终端上
stderr     标准错误输出流指针     
```

3. man手册

$man man     查看man手册

```c
       1   可执行程序或 shell 命令
       2   系统调用(内核提供的函数)     文件IO
       3   库调用(程序库中的函数)      标准IO
           
man 手册默认会从第一卷开始查找,

【2】标准IO函数

1. 常见的标准IO函数
fopen / fclose     打开/关闭一个文件
fprintf / fscanf
fputc     / fgetc
fgets     / fputs
fwrite  / fread
fseek     修改文件偏移量

 1)fopen
功能:打开一个文件;
头文件:
       #include <stdio.h>
原型:
       FILE *fopen(const char *pathname, const char *mode);
参数:
    char *pathname:指定要打开的文件路径+文件名;
    char *mode:打开方式;
       r      以读的方式打开文件;
                如果文件不存在,则打开失败;

r+     以读写的方式打开文件;
                如果文件不存在,则打开失败;

w      以写的方式打开文件;
                   如果文件不存在则创建文件;
                   如果文件存在则清空文件;

w+     以读写的方式打开文件;
                   如果文件不存在则创建文件;
                   如果文件存在则清空文件;

a      以写的方式打开文件;
                   如果文件不存在则创建文件;
                   如果文件存在则以追加的方式写;

a+     以读写的方式打开文件;
                   如果文件不存在则创建文件;
                   如果文件存在则以追加的方式写;
返回值:
     成功,返回流指针;
     失败,返回NULL,并设置错误码(errno);

例子:
    FILE* fp = fopen("./1.txt", "r");

 2)perror
功能:根据错误码errno,显示不同的错误信息;
头文件:
       #include <stdio.h>
原型:
       void perror(const char *s);
参数:
    char *s:用于提示的字符串;

#include<errno.h>
errno:本质上是一个全局变量,对应了各种错误,perror就是根据errno打印错误信息的
cd /usr/include/asm-generic/
    
例子:
     perror("fopen");

 3)fclose
功能:关闭文件,销毁缓冲区;
头文件:
       #include <stdio.h>
原型:
       int fclose(FILE *stream);
参数:
    FILE *stream:指定要关闭的流指针;
返回值:
    成功,返回0;
    失败,返回EOF(-1),更新errno;

4)fprintf
功能:将数据格式化输入到文件中;
头文件:
       #include <stdio.h>
原型:
       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
参数:
    FILE *stream:指定要输出到的流指针;
    char *format:格式化;
    ...:不定参数;
返回值:
    成功,返回被打印的字节个数; >0;
    失败,返回负数;

 5)fscanf
功能:将文件中的数据格式化输入到内存中;
头文件:
       #include <stdio.h>
原型:
       int scanf(const char *format, ...);
       int fscanf(FILE *stream, const char *format, ...);
参数:
    FILE *stream:指定要输入的流指针;
    char *format:格式化;
    ...:不定参数;
返回值:
    成功,返回获取到的数据个数;
    失败或者读取到文件结尾,返回EOF;

6)fputc
功能:将单个字符输出到文件中;
头文件:
       #include <stdio.h>
原型:
       int putchar(int c);
       int fputc(int c, FILE *stream);
参数:
    int c:指定要输出的字符,可以填字符类型,也可以填对应的整型;
    FILE *stream:流指针;
返回值:
    成功,返回输出的字符对应的整型;
    失败,返回EOF;

 7)fgetc
功能:从文件中获取单个字符;
头文件:
       #include <stdio.h>
原型:
       int getchar(void);
       int fgetc(FILE *stream);
参数:
    FILE *stream:流指针;
返回值:
    成功,返回获取到的字符;
    失败或者读取到文件结尾,返回EOF;

8)缓冲区

标准IO中所有的数据都输存储在缓冲区中,然后输出到硬件中

i. 全缓冲

**操作对象**

​        对普通文件进行操作(调用fopen函数打开的文件),通过FILE* fp流指针维护该缓冲区;

**大小**

​        4K = 4096byte = 4*1024;
    //由于系统优化,当打开文件,但是不操作的时候,不会真正的申请缓冲区
    fputc('a', fp);
    printf("%ld\n", fp->_IO_buf_end - fp->_IO_buf_base); //4096

**刷新缓冲区的方式**

1. 缓冲区满

2. fflush函数强制刷新缓冲区
          #include <stdio.h>
          int fflush(FILE *stream);

3. 关闭流指针 fclose

4. 主函数调用retrun退出

5. 调用exit函数
          #include <stdlib.h>
          void exit(int status);
   目前只要理解该函数能退出进程;
   int status:随便填一个整型即可;
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, const char *argv[])
{
    FILE* fp = fopen("./1.txt", "w");
    if(NULL == fp)
    {
        perror("fopen");
        return -1;
    }

/*
    
    //由于系统优化,当打开文件,但是不操作的时候,不会真正的申请缓冲区
    fputc('a', fp);
    printf("%ld\n", fp->_IO_buf_end - fp->_IO_buf_base); //4096
*/

/*
    //缓冲区满
    int i = 0;
    while(i<4096+1)
    {
        fputc('a', fp);
        i++;
    }
    */

/*
    //fflush强制刷新缓冲区
    fputc('b', fp);
    fflush(fp);
    */

/*
    //关闭流指针
    fputc('c', fp);
    fclose(fp);
    */

/*
    fputc('d', fp);
    return 0;
    */

fputc('e', fp);
    exit(0);

while(1)
        sleep(1);

fclose(fp);

return 0;
}
 ii.行缓冲

**操作对象**

​    标准输入(stdin),标准输出(stdout)

**大小**

​    1K = 1024byte

```c
printf("%ld\n", stdout->_IO_buf_end - stdout->_IO_buf_base);
```

**刷新缓冲区**

1. 缓冲区满

2. fflush函数强制刷新缓冲区

```c
          #include <stdio.h>
          int fflush(FILE *stream);
   ```

3. 关闭流指针 fclose

4. 主函数调用retrun退出

5. 调用exit函数

```c
          #include <stdlib.h>
          void exit(int status);
   目前只要理解该函数能退出进程;
   int status:随便填一个整型即可;
   ```

6. 遇到'\n'字符

7. 遇到输入函数,例如scanf fgets fscanf fgetc

iii.无缓冲

**操作对象**

​    标准错误输出(stderr)

**大小**

​    0, perror调用的就是stderr流指针

9)fputs
功能:将字符串输出到文件中;
头文件:
       #include <stdio.h>
原型:
       int puts(const char *s);
       int fputs(const char *s, FILE *stream);
参数:
    char *s:指定要输出的字符串的首地址;
    FILE *stream:指定要输出到哪个流指针对应的缓冲区中;
返回值:
    成功,返回非负数;
    失败,返回EOF;

例子:
    //打开文件:以写的方式打开
    FILE* fp = fopen("./fputs.abc", "w");
    if(NULL == fp) 
    {   
        perror("fopen");
        return -1; 
    }

fputs(str, fp);

10)fgets
功能:从指定文件中获取字符串,包括空格;
头文件:
       #include <stdio.h>
原型:
       char *gets(char *s);
       char *fgets(char *s, int size, FILE *stream);
参数:
    char *s:存储获取到的字符串;
    int size:指定要获取的字符串大小;最多读取size-1个字节,因为要保留'\0'位,fgets会自动填充最后的'\0'位;
                注意:fgets只能识别到'\n';
                假设一行有10个字节,fgets读取20个字节,实际读取10个字节,一次不会读取到下一行;
    FILE *stream:指定要从哪个流指针的缓冲区中获取;
返回值:
    成功,返回s,即字符串首地址;
    失败或者读取到文件结尾,返回NULL;

IO输入输出及标准IO函数相关推荐

  1. linux 一次io大小,Linux——标准IO篇

    主要知识点: 标准IO(fopen.perror.fputc.fgetc,stdin.三种缓冲区.读写偏移.fseek.ftell.fgets.fputs) [主要内容] [1]IO IO: inpu ...

  2. 文件IO open 与 标准 IO fopen 的对应

    FILE *fp: int fd: fp = fopen("1.c", "r");等价于 fd = open("1.c",O_RDONLY) ...

  3. Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)

    1.linux系统如何管理文件 硬盘中的静态文件和inode: (1)硬盘分为两大区域:一个是硬盘内容管理表项,另一个是真正存储内容的区域.先去读取硬盘内容管理表,找到要访问的存储内容的区域,再用得到 ...

  4. linux read函数_浅谈Linux内核IO体系之磁盘IO

    前言 Linux I/O体系是Linux内核的重要组成部分,主要包含网络IO.磁盘IO等.基本所有的技术栈都需要与IO打交道,分布式存储系统更是如此.本文主要简单分析一下磁盘IO,看看一个IO请求从发 ...

  5. 应用编程课程4.系统IO和标准IO的比较,自己做的一些理解,仅仅方便自己看

    /* 1.注意fseek实际上是调用lseek来实现的, 比较以下标准io与文件io的区别 注意:在stream这个概念中,有三个标准流stdin.stdout.stderr,,在我们当前这个文件描述 ...

  6. LinuxC—标准IO与文件IO学习笔记

    标准IO与文件IO 1 概述 stdio 标准IO(优先使用) sysio 系统调用IO(文件IO) sysio是直接实现用户态切换内核态,sysio和平台是有关系的,比如windows和linux, ...

  7. 海康工业相机功能模块-IO输入输出控制

    海康工业相机功能模块sdk调用介绍 IO输入输出控制 前言 IO输入 IO输出 前言 机器视觉行业里面,相机作为最重要的图像传感器,除了主要的拍摄功能外,它也承担了一部分信号控制功能. 一方面能够接受 ...

  8. Linux什么是文件IO,linux中文件IO

    一. linux常用文件IO接口 1.1. 文件描述符 1.1.1. 文件描述符的本质是一个数字,这个数字本质上是进程表中文件描述符表的一个表项,进程通过文件描述符作为index去索引查表得到文件表指 ...

  9. linux 流函数,标准IO函数库 - 二进制文件IO,流定位,创建临时文件和内存流

    1 二进制IO(Binary IO) 在前一篇我们了解了逐字符读写和逐行读写函数. 如果我们在读写二进制文件,希望以此读写整个文件内容,这两个函数虽然可以实现,但是明显会很麻烦且多次循环明显效率很低. ...

最新文章

  1. 2.7-egrep及bash中的变量
  2. 因为征信原因,买房的2万定金没了
  3. 遥感、制图学中各种图的区别
  4. 计算机系统结构安全检测,信息安全体系结构安全测评实验报告.doc
  5. java实现定时任务 schedule_Java定时任务的三种实现方式
  6. 学习日志---hbase学习(最大版本查询)
  7. 使用RTL-SDR打开车门
  8. 走一波 程序员必备精品软件大全
  9. 解析力 (2)空间采样 和 奈奎斯特
  10. SRIO传输协议学习
  11. 禁止在计算机上玩电子游戏,如何禁止孩子玩电脑游戏防止过度沉迷影响学习成绩...
  12. Linux 返回根目录,返回主目录
  13. Web.xml 错误或异常页面配置
  14. vhdl timing requirements not met 错误 quartusII中
  15. vue字符云-------把老婆放到云端
  16. c语言专业教学,C语言在计算机专业中的教学.docx
  17. 自制FOC控制驱动器
  18. 前端性能优化之图片优化
  19. Java---子类父类继承顺序
  20. 操作系统原理和实践-考前最后一练

热门文章

  1. 【离散数学】帕斯卡三角形与二项式定理
  2. Anaconda环境安装skimage包
  3. 2018年6月湖北自考计算机,2018年湖北自考考试注意事项
  4. TargetScan:哺乳动物miRNA靶基因数据库
  5. 微信小程序—点击按钮实现页面跳转
  6. 编写简单的WEB服务器
  7. LiveGBS国标平台可通过GB28181接入海康大华宇视等摄像头设备或平台Linux非root 用户启动和停止
  8. html+css3 3d导航栏
  9. 分享一篇十分钟学会正则表达式教程
  10. Uncaught SyntaxError: Unexpected identifier错误解决分析