【Linux文件IO】Linux中标准IO的API的描述和基本用法

server/2025/3/31 6:14:08/

Linux中标准IO的API的描述和基本用法

  • 一、标准IO相关API
    • 1、文件的打开和关闭
      • 示例代码:
    • 2、文件的读写
      • 示例代码:
      • 用标准IO(fread、fwrite)实现文件拷贝(任何文件均可拷贝)
    • 3、文件偏移设置
      • 示例代码:
    • 4、fgets fputs fgetc fputc gets puts putchar getchar putc getc
      • 示例代码:
        • (1) fgets按行读取数据
        • (2) fputs写入数据到文件
        • (3) fgets和fputs另外一个功能(标准输入和标准输出)
        • (4) fgetc读取一个字符和fputc写入一个字符
    • 5、判断是否到达文件末尾
      • 示例代码:
    • 6、fprintf和fscanf()
      • 示例代码:
    • 7、主动刷新缓冲区
      • 示例代码:
  • 二、对比系统IO和标准IO的区别
    • 1、
    • 2、
    • 3、

一、标准IO相关API

1、文件的打开和关闭

在这里插入图片描述
注意:

  • 总共有6中打开模式,不能自创别的模式,比如 “rw” 是非法的。
    在这里插入图片描述
    注意:
  • fclose函数涉及内存释放,不可对同一个文件多次关闭

示例代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{FILE * fp;// 以只读方式打开文件,要求文件必须存在// fp = fopen("1.txt", "r"); //  文件打开失败 提示: No such file or directory// 以读写方式打开文件,要求文件必须存在// fp = fopen("1.txt", "r+"); //  文件打开失败 提示: No such file or directory// 以只写方式打开文件,不存在就新建,存在则清空fp = fopen("1.txt", "w"); // if (fp == NULL){perror("文件打开失败\n");return -1;}// 关闭文件fclose(fp);return 0;
}

2、文件的读写

//按照数据块来读取数据
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);返回值(重点):成功 返回读取到的完整的数据块的个数失败  -1参数:ptr --》存放读取的内容size(重点) --》要读取的数据块大小,字节nmemb(重点) --》打算读取多少个数据块stream --》要读取的那个文件比如:read(fd,buf,100);  fread(buf,50,2)//读取2个数据块,每个数据块50个字节fread(buf,20,5)//读取5个数据块,每个数据块20个字节fread(buf,10,10)//读取10个数据块,每个数据块10个字节fread(buf,1,100)//读取100个数据块,每个数据块1个字节 情况1:如果文件剩余的字节数>=100个字节,以上四种写法都可以成功读取100个字节区别就是返回值不同情况2:如果文件剩余的字节数<100个字节,以上四种写法都可以成功读取剩余所有的字节区别就是返回值不同size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);返回值(重点): 成功      nmemb是多少,返回值就是多少参数:ptr --》存放要写入的内容size(重点) --》要写入的数据块大小,字节nmemb(重点) --》打算写入多少个数据块stream --》要写入的那个文件总结:无论write还是fwrite写入的字节数搞多了,都会找垃圾凑够需要写的字节数fwrite第三个参数写的是多少,返回值就是多少

示例代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>/*fread返回值:返回完整数据块个数fwrite返回值:nmemb是多少,返回值就是多少
*/int main(int argc, char const *argv[])
{FILE *fp = fopen("1.txt", "r+");int ret = 0;  if (fp == NULL){perror("打开文件失败\n");return -1;}char buf[20] = "helloword";// ret = fread(buf, 10, 1, fp); // 读取1个数据块,数据块大小为10个字节  读取的内容是:1234567890// fread(buf, 5, 2, fp); // 读取2个数据块,数据块大小为5个字节 读取的内容是:1234567890// ret = fread(buf, 1, 10, fp); // 读取10个数据块,数据块大小为1个字节  读取的内容是:1234567890// fread(buf, 2, 5, fp); // 读取5个数据块,数据块大小为2个字节 读取的内容是:1234567890// ret = fread(buf, 6, 2, fp);// printf("读取的内容是:%s\n", buf);// printf("fread的返回值ret:%d\n", ret);ret = fwrite(buf, 10, 1, fp);printf("fwrite的返回值ret:%d\n", ret);return 0;
}

用标准IO(fread、fwrite)实现文件拷贝(任何文件均可拷贝)

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{char buf[100] = {0};int ret = 0;FILE *fp1 = fopen("1.txt", "r+");if (fp1 == NULL){perror("打开文件失败\n");return -1;}FILE *fp2 = fopen("new.txt", "w+");if (fp1 == NULL){perror("新建文件失败\n");return -1;}while (1){bzero(buf, 100);// 每次读取100字节,即读取100个数据块,每个数据块1字节ret = fread(buf, 1, 100, fp1); // 读取完成则退出循环if (ret == 0) {break;}// 写入到目标文件fwrite(buf, 1, ret, fp2);}fclose(fp1);fclose(fp2);return 0;
}

3、文件偏移设置

在这里插入图片描述

示例代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{char buf[100] = {0};int ret = 0;FILE *fp1 = fopen("1.txt", "r+");if (fp1 == NULL){perror("打开文件失败\n");return -1;}// 从起始位置往后偏移5个字节,返回值与lseek不一样,0:成功, -1:失败ret = fseek(fp1, 5, SEEK_SET);printf("fseek的返回值是:%d\n", ret); // fseek的返回值是:0// 获取当前光标距离起始位置的字节数printf("当前光标距离起始位置的字节数:%ld\n", ftell(fp1)); // 当前光标距离起始位置的字节数:5// 读取文件,从第六个字节开始读取fread(buf, 1, 5, fp1);// 偏移后读取的数据是:world 若读取数据有误,现在linux中手动删除(rm 1.txt)在新建(vim 1.txt)printf("偏移后读取的数据是:%s\n", buf); // 关闭文件fclose(fp1);return 0;
}

4、fgets fputs fgetc fputc gets puts putchar getchar putc getc

char *fgets(char *s, int size, FILE *stream);  //按行读取数据,一次最多读取一行(遇到回车结束读取)返回值:成功  返回读取的一行数据的首地址失败  NULL参数:s  --》存放读取到的一行数据size --》打算读取多少字节的数据stream --》要从哪个文件读取一行特点:假如一行只有10个字符fgets(buf,5,myfile); //只能读取4个有效字符,最后一个fgets会帮你填充\0fgets(buf,11,myfile); //前面10个是有效字符,第11个是\0fgets(buf,12,myfile); //前面11个是有效字符(会把回车\n读取,windows上的回车是\r\n),第12个是\0
int fputs(const char *s, FILE *stream);  //往一个文件中写入字符串返回值:成功  >0   失败  -1  参数:s --》要写入的内容stream --》要写入的那个文件  fputs有局限性(char *),只能写入字符串,但是fwrite可以写任意类型(void *)的数据int fgetc(FILE *stream);  //按字符读取数据,一次只能读取一个字节的数据返回值:读取到的那个字符的ASCII码值失败 -1
int fputc(int c, FILE *stream);  //把c这个字符写入到stream表示的文件中char *gets(char *s);  //只能读取键盘输入的字符串,把字符串保存到s中
int puts(const char *s) //把s这个字符串在标准输出(液晶屏)上打印出来int getc(FILE *stream);   //按字符读取数据,一次只能读取一个字节的数据
int putc(int c, FILE *stream);  //把c这个字符写入到stream表示的文件中int getchar(void);       //从IO缓冲区读取一个字符
int putchar(int c);      //把c代表的字符在液晶屏上打印出来

示例代码:

(1) fgets按行读取数据
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>/*fgets按行读取文件特点:fgets遇到回车就结束读取,并且会把回车也读取出来特点:   假如一行只有10个字符fgets(buf,5,myfile); //只能读取4个有效字符,最后一个fgets会填充\0fgets(buf,11,myfile); //前面10个是有效字符,第11个是\0fgets(buf,12,myfile); //前面11个是有效字符(会把回车\n读取,windows上的回车是\r\n),第12个是\0
*/
int main(int argc, char const *argv[])
{char buf[100] = {0};int ret = 0;FILE *fp1 = fopen("1.txt", "r+");if (fp1 == NULL){perror("打开文件失败\n");return -1;}// 每一轮读取一行数据 // for (int i = 0; i < 3; i++)// {// bzero(buf, 0);//     fgets(buf, 100, fp1);//     printf("buf :%s\n", buf);// }
/* 
原始数据:helloworld你好你最棒 
执行结果:buf :helloworldbuf :你好buf :你最棒 */// 第二个参数需要设置到足够大,否则一直读取第一行数据直至读完才会读取第二行数据bzero(buf, 100);fgets(buf,5,fp1);printf("buf :%s\n", buf);bzero(buf, 100);fgets(buf,5,fp1);printf("buf :%s\n", buf);bzero(buf, 100);fgets(buf,5,fp1);printf("buf :%s\n", buf);
/* 
原始数据:helloworldnihaonihaohelloworld
执行结果:buf :hellbuf :oworbuf :ld
*/// 关闭文件fclose(fp1);return 0;
}
(2) fputs写入数据到文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{char buf[100] = {0};int ret = 0;FILE *fp1 = fopen("1.txt", "r+");if (fp1 == NULL){perror("打开文件失败\n");return -1;}// 写入字符串fputs("hello", fp1);fputs("world", fp1);fseek(fp1, 0, SEEK_SET);fread(buf, 1, 100, fp1);printf("buf:%s\n", buf);// 关闭文件fclose(fp1);return 0;
}
(3) fgets和fputs另外一个功能(标准输入和标准输出)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{char buf[100] = {0};// fgets读取键盘输入的字符串(标准输入)printf("fgets从键盘输入一个字符串:");fgets(buf, 100, stdin);// fputs写入字符串到液晶屏(标准输出)printf("fputs从液晶屏输出一个字符串:");fputs(buf, stdout);return 0;
}/* 
执行结果:fgets从键盘输入一个字符串:nihaofputs从液晶屏输出一个字符串:nihao 
*/
(4) fgetc读取一个字符和fputc写入一个字符
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{char buf[100] = {0};int ret = 0;FILE *fp1 = fopen("1.txt", "r+");if (fp1 == NULL){perror("打开文件失败\n");return -1;}// 读取一个字节ret = fgetc(fp1);printf("读取到的内容:%c, %d\n", ret, ret);  // 读取到的内容:h, 104fputc('#', fp1);fseek(fp1, 0, SEEK_SET);fread(buf, 1, 100, fp1);printf("写入#后的内容是:%s\n", buf); // 写入#后的内容是:h#lloworld// 关闭文件fclose(fp1);return 0;
}

5、判断是否到达文件末尾

int feof(FILE *stream);返回值:1 表示达到文件末尾

示例代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{char buf[100] = {0};FILE *fp = fopen("1.txt", "r+");if (fp == NULL){perror("打开文件失败\n");return -1;}while(1){bzero(buf, 100);char *ret = fgets(buf, 100, fp);printf("读取到一行的数据:%s\n", buf);// 方法1:通过fgets和fread的返回值判断// if (ret == NULL)// {//     printf("读取完毕\n");//     break;// }// 方法2:使用feof函数判断if (feof(fp) == 1){printf("读取完毕\n");break;}}fclose(fp);return 0;
}/* 执行结果:读取到一行的数据:h#lloworld读取到一行的数据:nihao读取到一行的数据:666666读取完毕 */

6、fprintf和fscanf()

   sprintf 拼接字符串printf  打印字符串
int fprintf(FILE *stream, const char *format, ...);  //按照指定格式,把数据合并写入到stream代表的文件中int fscanf(FILE *stream, const char *format, ...);  //按照指定格式,把数据读取出来fscanf读取指定格式的数据
如果指定的格式是%s,fscanf会把整个文件内容都当成是字符串

示例代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{/* fprintf 把字符串拼接好写入指定的文件中 */char read_buf[100] = {0};char *buf = "hello";int year = 2025;float score = 99.9;FILE *fp = fopen("2.txt", "w+");if (fp == NULL){perror("打开文件失败\n");return -1;}fprintf(fp, "%s%d-%f", buf, year, score);// 写完后此时光标移至末尾,需要将光标重新移至开头fseek(fp, 0, SEEK_SET);// 读取文件fread(read_buf, 1, 100, fp);printf("read_buf:%s\n", read_buf); // read_buf:hello2025-99.900002// 关闭文件fclose(fp);/* fscanf 把文件中的内容读取并拆分 */char *write_buf = "2025-01-01";int y,m,d;FILE *fp2 = fopen("3.txt", "w+");if (fp2 == NULL){perror("打开文件失败\n");return -1;}// 写入文件fwrite(write_buf, 1, strlen(write_buf), fp2);// 写入文件时会将光标移至文件末尾。需要将光标重新移至开头fseek(fp2, 0, SEEK_SET);// 把文件中的内容读取并拆分fscanf(fp2, "%d-%d-%d", &y, &m, &d);printf("年:%d\n", y);printf("月:%d\n", m);printf("日:%d\n", d);return 0;
}
/* 
执行结果:read_buf:hello2025-99.900002年:2025月:1日:1 
*/

7、主动刷新缓冲区

正常情况下标准IO是带缓冲区:情况一:缓冲区满了,自动刷新情况二:缓冲区没有满,主函数return退出的时候也会自动刷新缓冲区情况三:fclose关闭文件的时候也会刷新缓冲区
int fflush(FILE *stream);返回值:成功:0   失败:-1

示例代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(int argc, char const *argv[])
{int n = 0;FILE *fp = fopen("4.txt", "r+");if (fp == NULL){perror("打开文件失败\n");return -1;}while (1){fwrite("hello", 1, 5, fp);sleep(1);fflush(fp); // 主动刷新缓冲区}fclose(fp);// return 0;
}

二、对比系统IO和标准IO的区别

1、

  • 系统IO采用文件描述符来表示文件
  • 标准IO采用FILE*来表示文件

2、

 系统IO        0         1            2#define  STDIN_FILENO        0    标准输入--》键盘#define  STDOUT_FILENO       1    标准输出--》液晶屏#define  STDERR_FILENO       2    标准错误输出--》液晶屏标准IO       stdin   stdout      stderrFILE *stdin;          标准输入--》键盘FILE *stdout;         标准输出--》液晶屏  FILE *stderr;         标准错误输出--》液晶屏

3、

  • 系统IO没有缓冲区
  • 标准IO带缓冲区

http://www.ppmy.cn/server/179728.html

相关文章

【软件测试】:软件测试实战

1. ⾃动化实施步骤 1.1 编写web测试⽤例 1.2 ⾃动化测试脚本开发 common public class AutotestUtils {public static EdgeDriver driver;// 创建驱动对象public static EdgeDriver createDriver(){// 驱动对象已经创建好了 / 没有创建if( driver null){driver new EdgeDr…

Spring Boot 连接 MySQL 配置参数详解

Spring Boot 连接 MySQL 配置参数详解 前言参数及含义常用参数及讲解和示例useUnicode 参数说明&#xff1a; 完整配置示例注意事项 前言 在 Spring Boot 中使用 Druid 连接池配置 MySQL 数据库连接时&#xff0c;URL 中 ? 后面的参数用于指定连接的各种属性。以下是常见参数…

Docker+Ollama+Xinference+RAGFlow+Dify+Open webui部署及踩坑问题

目录 一、Xinference部署 &#xff08;一&#xff09;简介 &#xff08;二&#xff09;部署 &#xff08;三&#xff09;参数 &#xff08;四&#xff09;错误问题 &#xff08;五&#xff09;Xinference配置Text-embedding模型 &#xff08;六&#xff09;Xinference配…

mysqloracledb2 (uuid函数)

项目场景&#xff1a; 创建一个32位的UUID 问题描述 原因分析&#xff1a; 解决方案&#xff1a; mysql内置UUID函数 SELECT UUID(); SELECT UUID_SHORT();oracle内置UUID函数 SELECT sys_guid() FROM dual;db2&#xff0c;模拟UUID函数 SELECT TEST || substr (CONCAT…

MySQL的查询语句练习

单表查询部分&#xff1a; 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等CREATE TABLE worker (部门号 int(11) NOT NULL,职工号 int(11) NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌…

使用ZMQ和protobuf实现C++程序与Python程序的通信

文章目录 背景一 应用场景与需求二 Protobuf: 跨语言数据交换的基石三 通信方案 ZMQ (ZeroMQ) —— 高性能消息中间件四 进阶: 安全性与性能优化五 实践例子: 工厂温度监控系统5.1 场景描述5.2 Protobuf数据结构定义5.3 C数据采集与发布5.4 Python数据接收与可视化5.5 关键实现…

Apache Shiro 统一化实现多端登录(PC端移动端)

Apache Shiro 是一个强大且易用的Java安全框架&#xff0c;提供了身份验证、授权、密码学和会话管理等功能。它被广泛用于保护各种类型的应用程序&#xff0c;包括Web应用、桌面应用、RESTful服务、移动端应用和大型企业级应用。 需求背景 在当今数字化浪潮的推动下&#xff…

在linux部署网站

在Linux部署网站&#xff0c;需要准备一个纯净的系统 一、系统环境准备 1.设置静态IP地址 ‌ 2.关闭默认防火墙 systemctl disable firewalld --now ‌ 3.配置SSH密钥登录 4.yum update -y && reboot # 更新系统内核 5.yum install -y wget curl unzip # 安装…