linux系统编程 标准io

简介: linux系统编程 标准io

一、标准IO概念

标准IO在系统调用的上一层多加了一个缓冲区,也因此引入了流的概念,在UNIX/Linux下表示为FILE*(并不限于UNIX/Linux,ANSI C都有FILE的概念),FILE实际上包含了为管理流所需要的所有信息:实际I/O的文件描述符,指向流缓存的指针(标准I/O缓存,由malloc分配,又称为用户态进程空间的缓存,区别于内核所设的缓存),缓存长度,当前在缓存中的字节数,出错标志等。标准I/O对每个I/O流自动进行缓存管理,它提供了三种类型的缓存:

  • 全缓存。当填满标准I/O缓存后才执行I/O操作。磁盘上的文件通常是全缓存的。
  • 行缓存。当输入输出遇到新行符或缓存满时,才由标准I/O库执行实际I/O操作。stdin、stdout通常是行缓存的。
  • 无缓存。相当于read、write了。stderr通常是无缓存的,因为它必须尽快输出。

二、行缓存的验证案例

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
       printf("hello world!");
       while(1)
       {       
              sleep(1);
       }
       return 0;
}    

以上程序编译后,并不能输出任何信息。原因是使用printf输出hello world后,没有换行符。printf的缓冲是属于行缓冲的,输出遇到新行符或缓冲满时,才执行标准的I/O操作。此程序由于执行到了while中的循环,一直在循环。缓冲没有满,也没遇到换行符。所以屏幕无任何输出。

当去掉while循环,程序输出后立马结束,缓存中的信息就会输出出来。

三、FILE结构体

包含于#include <stdio.h>里,以下仅是FILE结构体部分参数,具体可查看头文件。

缓存的操作如下:

缓存遇到换行符或是return/exit(_exit不行) 或者写满缓存或者调用fclose后的时候,才会输出。

数据先写进缓存,然后再输出到文件或屏幕上。

stdin:标准输入,scanf 类函数就是默认的使用此函数

stdout:标准输出,printf 函数默认使用此

stderr:标准错误

这三个就是FILE 类型结构体指针,也称为流指针

四、函数格式定义

1. fopen()函数 – 用于打开一个文件,返回一个指向该文件的文件指针

#include<stdio.h>
FILE* fopen(const char *filename, const char *mode);
  • 函数描述:fopen 打开一个指定的文件。
  • 参数说明:
filename:指定了被打开的文件的路径(相对路径或绝对路径)
 mode:指定了被打开文件的操作方式,如下:
   “r”:只读
   “w”:只写,并将文件截断为0
   “a”:只写,以追加方式从文件尾开始写
   “r+”:读写
   “w+”:读写,并将文件截断为0
   “a+”:读写,以追加方式从文件尾开始写
  • 函数返回值:
成功:指向FILE的指针
 失败: NULL

2. fdopen()函数 – 把流与一个文件句柄相接

#include<stdio.h>
FILE * fdopen(int fd,  const char * mode);
  • 函数描述:通俗的理解fdopen就是把参数fd的文件描述符转化为文件指针。
  • 参数说明:
fd: 文件描述符
 mode: 文件打开的模式。和fopen中的模式(如r-只读, w-写)相同。
  • 函数返回值:
返回文件指针。

3. freopen()函数 --预定义的标准流文件定向到由path指定的文件中

#include <stdio.h>
FILE *freopen( const char *path, const char *mode, FILE *stream ); 
  • 函数描述:
实现重定向,把预定义的标准流文件定向到由path指定的文件中。标准流文件具体是指stdin、stdout和stderr。
  其中stdin是标准输入流,默认为键盘;stdout是标准输出流,默认为屏幕;stderr是标准错误流,一般把屏幕设为默认。
  • 参数说明:
path: 文件名,用于存储输入输出的自定义文件名。
 mode: 文件打开的模式。和fopen中的模式(如r-只读, w-写)相同。
 stream: 一个文件,通常使用标准流文件。
  • 函数返回值:
成功,则返回一个path所指定文件的指针;失败,返回NULL。

4. fread()函数 – 用于从一个文件流中读取数据

#include<stdio.h>
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
  • 函数描述:
它与底层调用read相似,其作用是从stream读取nitems个长度为size的数据到ptr所指向的缓冲区中。
  • 参数说明:
ptr: 指定从文件流中读取的数据所存放的地方
 size: 指定所读取的每一条记录的大小,单位字节
 items: 指定本次读操作所读取的记录条数
 stream: 指定读取数据的来源—文件流
  • 函数返回值:
fread执行成功时返回实际读取记录的条数。

5. fwrite()函数 – 用于写数据到一个文件流中

#include<stdio.h>
size_t fwrite(void *ptr, size_t size, size_t nitems, FILE *stream);
  • 函数描述:
它与底层调用write相似,其作用是从stream写nitems个长度为size的数据到ptr所指向的缓冲区中。

6. fclosed函数

#include<stdio.h>
int fclose(FILE *stream);
  • 函数描述:
fclose操作将会引起所要关闭的文件流刷新缓冲区的操作,这使得该文件流上的所有读写操作都立刻执行。当程序正常终止时
    (return/exit两个函数可以,_exit不行)会对所有尚未关闭的文件流自动执行fclose操作。
  • 参数说明:
stream: 指定断开数据的来源—文件流
  • 函数返回值:
成功返回0
 失败返回EOF

7. fflush()函数

#include<stdio.h>
int fflush(FILE *stream);
  • 函数描述:
清除一个流,即清除文件缓冲区,当文件以写方式打开时,将缓冲区内容写入文件。也就是说,对于ANSI C规定的是缓冲文件系
    统,函数fflush用于将缓冲区的内容输出到文件中去。
  • 参数说明:
stream: 指定刷新数据的来源—文件流
  • 函数返回值:
如果成功刷新,fflush返回0。指定的流没有缓冲区或者只读打开时也返回0值。
 失败返回EOF指出一个错误。

8. fgetc、getc、getchar – 从指定文件流中读取一个字节的数据

#include<stdio.h>
int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar();
  • 函数描述:
函数fgetc从指定的文件流中读取一个字节的数据,并返回该字节数据的整型值,当读到文件尾或发生错误时返回EOF。getc同
    fgetc,只是它有可能被实现为宏。getchar函数相当于从标准输入读取字节时的fgetc。
  • 参数说明:
stream: 指定获取数据的来源—文件流
  • 函数返回值:
成功返回该字节数据的整型值。
 失败返回EOF指出一个错误。

9. fputc、putc、putchar – 写一个字节数据到指定的文件流

#include<stdio.h>
int fputc(int c, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);
  • 函数描述:
fputc函数将一个字节写到指定的文件流中,成功时返回返回写入的字节的整型值,失败时返回EOF。putc同fputc,只是有可能
    被实现为宏。putchar相当于向标准输出写一个字节时的fputc。
  • 参数说明:
stream: 指定写入数据的来源—文件流
  • 函数返回值:
成功返回该字节数据的整型值。
 失败返回EOF指出一个错误。

10. fgets、gets – 用于从一个文件流读取一个字符串

#include<stdio.h>
char *fgets(char *s, int n, FILE *stream);
char *gets(char *s);
  • 函数描述:
fgets函数从指定的文件流指针中读取一个字符串,直到遇到换行符或者已经读了n-1个字符或者遇到文件EOF,它会在所读取的
    数据结尾加上一个\0字符,然后放到s指定的位置。
  • 参数说明:
stream: 指定读取数据的来源—文件流
 s: 指定存放所读取的数据的位置
 n: 指定读取数据的最大长度(包括结尾的\0字符)
  • 函数返回值:
成功返回返回指向s的指针
 失败返回NULL
目录
相关文章
|
1天前
|
SQL 监控 架构师
linux系统性能分析的目的
【4月更文挑战第19天】在Linux系统中,找到性能瓶颈是关键,涉及应用程序、操作系统、硬件和网络的全面排查。优化方案通常针对应用程序和操作系统,而硬件和网络问题较易定位。目标是平衡资源使用,确保系统响应和稳定性。系统管理员、架构设计人员和开发人员共同参与,通过监控硬件、网络、配置和代码来优化性能。流程包括管理员初步判断,架构师处理结构问题,开发人员优化代码,实现系统资源的均衡利用。
6 1
|
2天前
|
人工智能 算法 调度
uvloop,一个强大的 Python 异步IO编程库!
uvloop,一个强大的 Python 异步IO编程库!
11 2
|
2天前
|
消息中间件 关系型数据库 MySQL
Linux:开源之魅与编程之道
Linux:开源之魅与编程之道
11 1
|
3天前
|
Ubuntu Linux
Linux(Ubuntu)系统临时IP以及静态IP配置(关闭、启动网卡等操作)
请注意,以上步骤是在临时基础上进行配置的。如果要永久保存静态IP地址,通常还需要修改 `/etc/network/interfaces`文件,以便在系统重启后保持配置。同时,确保备份相关配置文件以防止出现问题。
15 1
|
4天前
|
Linux 数据安全/隐私保护
Linux系统忘记密码的三种解决办法
这篇博客介绍了三种在Linux忘记密码时重置登录密码的方法:1) 使用恢复模式,通过控制台界面以管理员权限更改密码;2) 利用Linux Live CD/USB启动,挂载硬盘分区并使用终端更改密码;3) 进入单用户模式,自动以管理员身份登录后重置密码。每个方法都提供了详细步骤,提醒用户在操作前备份重要数据。
|
4天前
|
JSON Unix Linux
Linux系统之jq工具的基本使用
Linux系统之jq工具的基本使用
32 2
|
4天前
|
数据采集 监控 安全
linux系统被×××后处理经历
linux系统被×××后处理经历
|
4天前
|
监控 安全 Linux
Linux系统之安装ServerBee服务器监控工具
【4月更文挑战第22天】Linux系统之安装ServerBee服务器监控工具
43 2
|
4天前
|
缓存 Linux
linux系统缓存机制
linux系统缓存机制
|
5天前
|
存储 Linux Android开发
RK3568 Android/Linux 系统动态更换 U-Boot/Kernel Logo
RK3568 Android/Linux 系统动态更换 U-Boot/Kernel Logo
20 0