【IO编程】文件IO的API

这篇文章在 文章:【文件I/O】文件持久化 的基础之上,更进一步的描述了文件IO中更多更详细的API详解。

文件IO

文件IO操作是必须要理解的环节之一,因为 s:套接字文件 ;p: 管道文件 —> 都需要通过文件IO来进行打开。

文件IO的特点

	1>文件IO没有缓冲区 
	2>文件IO源于底层,有系统的地方就能使用文件IO 
	3>文件IO操作比较复古
	4>文件IO的操作核心:文件描述符(通过文件描述符来访问文件)
	
文件I/O
    不带缓冲
     	 不带缓冲指的是每个read和write都调用内核中的相应系统调用   --->开销很大
    	 不带缓冲的I/O函数不是ANSI C的组成部分,但是是POSIX和XPG3的组成部分--->文件IO来自系统底层
    通过文件描述符来访问文件-----**
    	对于内核而言,所有打开文件都由文件描述符引用。
        文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。
        当读、写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write。
        在posix.1应用程序中,幻数0、1、2应被代换成符号常数STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO。
        这些常数都定义在头文件<unistd.h>中。

文件IO的API学习:

文件IO操作的层面 和 系统底层非常有关系 ***
	1> 打开文件 
		open
	    #include <sys/types.h>
        #include <sys/stat.h>
        #include <fcntl.h>

       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);
       功能: 
       		打开 文件 ,并返回 该文件的文件描述符 
       参数: 
       		pathname:带路径文件名 
       		flags:打开的方式
       		mode:*****--->隐藏开启参数 
       返回值: 
       		成功返回 该文件的文件描述符 
       		失败返回 -1,并设置错误码 
   open的重点; 
   		flags:打开的方式
   			三个必选项:互斥-->三选一 
   			O_RDONLY	只读
   			O_WRONLY	只写
   			O_RDWR		读写
   			其他都是可选项:
   			O_CREAT:	创建-->如果文件不存在,则创建
   			O_TRUNC:	清空模式
   			O_APPEND:	追加模式
   			O_NOCTTY:	使用本参数时,如文件为终端,那么终端不可以作为调用open()系统调用的那个进程的控制终端。
		mode:*****--->隐藏开启参数 
			如果你的flags参数中具有O_CREAT-->那么就会开启mode参数(第三个参数)
			mode:设置你创建文件的权限 
	标准IO的打开方式   VS   文件IO的打开方式 
	r 					 O_RDONLY
	r+					 O_RDWR
	w 					 O_WRONLY|O_CREAT|O_TRUNC,0666
	w+ 					 O_RDWR|O_CREAT|O_TRUNC,0666
	a 					 O_WRONLY|O_CREAT|O_APPEND,0666
	a+					 O_RDWR|O_CREAT|O_APPEND,0666
	
		open  和 fopen 的区别:
		 1> 头文件差别很大:
		 	open:三个头文件:sys/types.h、sys/stat.h、fcnt1.h --->系统头文件:来自系统库
		 	fopen:一个头文件:stdio.h
		 2> fopen 和 open 使用的场景有什么区别?
		 	fopen: 标准IO的打开: 作用仅用来负责IO操作
		 	open:  文件IO的打开: 作用很广泛:
		 			1> 打开系统的特殊文件:p文件	和 s文件 b文件 c文件
		 				open打开p文件时,你可以使用p文件本身的特点: 管道通信
		 			简单点说:
		 				标准IO的fopen仅用来IO操作
		 				文件IO的open可以用来操作底层

		touch创建还是open创建,都要收到掩码 ---> 默认掩码:0002
			创建文件:默认权限:0666
			创建目录:默认权限:0777
			但是,它们权限会受到掩码的影响 
		实际权限:默认权限 - 掩码权限: 0666 - 0002 =0664
		        默认权限 - 掩码权限: 0777 - 0002 =0775
		       
	2> 操作文件-------文件IO的基本操作流程:1. 打开文件;2. 读写文件;3. 关闭文件;
		read-->读取 
		#include <unistd.h>
        ssize_t read(int fd, void *buf, size_t count);
        功能: 
        	从相应的文件描述符中,读取数据 
        参数: 
        	1>fd:文件描述符 
        	2>buf:读取出来的数据存放的地方 char buf[100];
        	3>count:读取的字符数大小 
        返回值: 
        	成功返回 读取到的字符数 
        	读到末尾返回0 
        	失败返回 -1,并设置错误码

		write-->写入 
	       #include <unistd.h>
       	   ssize_t write(int fd, const void *buf, size_t count);
       	功能: 
        	将数据 写入到 相应的文件描述符
        参数: 
        	1>fd:文件描述符 
        	2>buf:写入的数据存放的地方 char buf[100];
        	3>count:写入的字符数大小 
        返回值: 
        	成功返回 写入到的字符数 
        	失败返回 -1,并设置错误码
    课堂练习: 
    	将 hello.c的内容(自定义)  读取后 写入到  nihao.c 中 --->一模一样只有文件名不同
    	
	3> 关闭文件 --->验证文件描述符的处理逻辑
		close
		#include <unistd.h>
        int close(int fd);
        功能: 
        	关闭文件描述符 
        参数: 
        	fd:文件描述符
        返回值: 
        	成功返回 0
        	失败返回 -1,并设置错误码

	4> 适用函数
		4.1> lseek(); //文件IO的光标控制 --->和fseek相比,少了个小弟
		#include <sys/types.h>
        #include <unistd.h> 
        off_t lseek(int fd, off_t offset, int whence);
        功能: 
        	文件IO的光标控制 
       	参数: 
       		fd:文件描述符 
       		offset:偏移量 
       		whence:起始位置/基准位置 
       			SEEK_SET:文件开头 
       			SEEK_CUR:当前位置 
       			SEEK_END:文件尾部
       	返回值: 
       		成功返回 光标当前位置的偏移量 
       		失败返回 -1,并设置错误码
       		
       	4.2> dup/dup2
       	#include <unistd.h>
        int dup(int oldfd);  //会自动创建newfd     
        功能; 
        	根据 oldfd 返回一个 newfd 
        	作用:绑定 文件描述符 : oldfd 返回 newfd -->newfd会继承 oldfd的东西 
        		操作newfd 等于 操作oldfd 
        参数: 
        	oldfd:必须是已开启的文件返回的文件描述符 
        返回值: 
        	成功返回 newfd 
        	失败返回 -1,并设置错误码
        	
		#include <unistd.h>
		int dup2(int oldfd, int newfd);
		功能; 
			将oldfd  和 newfd 进行绑定 
			情况: oldfd必须已存在,newfd无所谓
				newfd:不存在则创建并且和oldfd绑定 
				newfd:已存在,会使原本newfd代表的文件失效,然后绑定
        参数: 
        	oldfd:必须是已开启的文件返回的文件描述符 
        返回值: 
        	成功返回 newfd 
        	失败返回 -1,并设置错误码

	标准IO的格式化IO:---> 可以掌握,将数据结构的数据链,保存在文件中---->自己悟
		int fprintf(FILE *stream, const char *format, ...);//将流的内容输出到屏幕上中
		int dprintf(int fd, const char *format, ...);//将文件描述符的内容输出到屏幕上中
        int sprintf(char *str, const char *format, ...);//将某地址内容输出到屏幕上 -->char buf[100];
        
        #include <stdio.h>
        int scanf(const char *format, ...);
        int fscanf(FILE *stream, const char *format, ...);//输入内容到流中
        int sscanf(const char *str, const char *format, ...);//输入内容到某地址上

请添加图片描述

文件指针操作

文件指针用于标识文件中当前的读写位置,操作文件指针可以实现文件的随机访问。

常用函数:

  1. fseek(FILE *stream, long offset, int origin)
    • 移动文件指针到指定位置。
    • origin 参数:
      • SEEK_SET:文件开头。
      • SEEK_CUR:当前位置。
      • SEEK_END:文件末尾。
  2. ftell(FILE *stream)
    • 返回当前文件指针的位置。
  3. rewind(FILE *stream)
    • 将文件指针重新定位到文件开头。

附代码

#include <stdio.h>

int main() {
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    fseek(file, 5, SEEK_SET); // 文件指针移动到第 5 个字节
    int pos = ftell(file);   // 获取文件指针位置
    printf("Current position: %d\n", pos);

    rewind(file); // 重置文件指针到开头
    fclose(file);
    return 0;
}

文件 I/O对于二进制文件操作

二进制文件操作允许程序以更高效的方式处理数据(如图像、音频等)。

读取二进制文件:

#include <stdio.h>

int main() {
    FILE *file = fopen("data.bin", "rb"); // 二进制读取
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    int buffer[10];
    fread(buffer, sizeof(int), 10, file); // 读取 10 个整数
    fclose(file);

    for (int i = 0; i < 10; i++) {
        printf("%d ", buffer[i]);
    }

    return 0;
}

写入二进制文件:

#include <stdio.h>

int main() {
    FILE *file = fopen("data.bin", "wb"); // 二进制写入
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    int data[] = {1, 2, 3, 4, 5};
    fwrite(data, sizeof(int), 5, file); // 写入数组
    fclose(file);

    return 0;
}

注意事项

  • 文件关闭:始终在完成操作后关闭文件,避免文件资源泄漏
  • 缓冲区刷新:写入文件时,数据可能被暂存于缓冲区,调用 fflush()fclose() 确保数据写入磁盘。
  • 权限检查:确保操作系统文件权限允许对文件进行读写操作。
  • 错误处理:文件操作可能失败(如文件不存在、磁盘空间不足等),应检查返回值并处理错误。

文件 I/O 是程序与外部存储设备交互的核心功能,涵盖了文件的打开、读取、写入、关闭等操作。使用文件 I/O可以实现高效的数据存储与处理。

综上。希望该内容能对你有帮助,感谢!

以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。

我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据库】Unity 使用 Sqlite 数据库

1.找到需要三个 DLL Mono.Data.Sqlite.dllSystem.Data.dllsqlite3.dll 上面两个dll可在本地unity安装目录找到&#xff1a; C:\Program Files\Unity\Hub\Editor\2022.3.xxf1c1\Editor\Data\MonoBleedingEdge\lib\mono\unityjit-win32 下面dll可在sqlite官网下载到&#xff…

省级-农业科技创新(农业科技专利)数据(2010-2022年)-社科数据

省级-农业科技创新&#xff08;农业科技专利&#xff09;数据&#xff08;2010-2022年&#xff09;-社科数据https://download.csdn.net/download/paofuluolijiang/90028570 https://download.csdn.net/download/paofuluolijiang/90028570 数据 年份、省份、农业科技专利数量…

51单片机——定时器中断(重点)

STC89C5X含有3个定时器&#xff1a;定时器0、定时器1、定时器2 注意&#xff1a;51系列单片机一定有基本的2个定时器&#xff08;定时器0和定时器1&#xff09;&#xff0c;但不全有3个中断&#xff0c;需要查看芯片手册&#xff0c;通常我们使用的是基本的2个定时器&#xff…

计算机的错误计算(二百零九)

摘要 利用两个大模型判断 是否为有理数&#xff1f;其值是多少&#xff1f;由实验知&#xff0c;其中一个大模型判断错误&#xff0c;说不是有理数&#xff1b;至于其值&#xff0c;该大模型选了一个错误的数值。 例1. e^(45*ln(24.8))是有理数吗&#xff1f;其值是多少&am…

Facebook 隐私变革之路:回顾与展望

在数字时代&#xff0c;个人隐私的保护一直是社交平台面临的重大挑战之一。作为全球最大的社交网络平台&#xff0c;Facebook&#xff08;现为Meta&#xff09;在处理用户隐私方面的变革&#xff0c;历经了多次调整与完善。本文将回顾Facebook在隐私保护方面的历程&#xff0c;…

第432场周赛:跳过交替单元格的之字形遍历、机器人可以获得的最大金币数、图的最大边权的最小值、统计 K 次操作以内得到非递减子数组的数目

Q1、跳过交替单元格的之字形遍历 1、题目描述 给你一个 m x n 的二维数组 grid&#xff0c;数组由 正整数 组成。 你的任务是以 之字形 遍历 grid&#xff0c;同时跳过每个 交替 的单元格。 之字形遍历的定义如下&#xff1a; 从左上角的单元格 (0, 0) 开始。在当前行中向…

GitLab CI/CD使用runner实现自动化部署前端Vue2 后端.Net 7 Zr.Admin项目

1、查看gitlab版本 建议安装的runner版本和gitlab保持一致 2、查找runner 执行 yum list gitlab-runner --showduplicates | sort -r 找到符合gitlab版本的runner&#xff0c;我这里选择 14.9.1版本 如果执行出现找不到下载源&#xff0c;添加官方仓库 执行 curl -L &quo…

机器学习基础-机器学习的常用学习方法

目录 半监督学习的概念 规则学习的概念 基本概念 机器学习里的规则 逻辑规则 规则集 充分性与必要性 冲突消解 命题逻辑 → 命题规则 序贯覆盖 单条规则学习 剪枝优化 强化学习的概念 1. 强化学习对应了四元组 2. 强化学习的目标 强化学习常用马尔可夫决策过程…

docker安装rabbit后访问报错最佳的几种解决方案

错误通常是由于RabbitMQ的安全配置导致的&#xff0c;RabbitMQ默认配置允许的用户仅能通过localhost访问。这通常出现在RabbitMQ的guest用户上&#xff0c;guest用户默认只能从localhost登录&#xff0c;而无法从其他IP地址进行远程访问。 解决方法&#xff1a; 1. **创建一个…

26个开源Agent开发框架调研总结(2)

根据Markets & Markets的预测&#xff0c;到2030年&#xff0c;AI Agent的市场规模将从2024年的50亿美元激增至470亿美元&#xff0c;年均复合增长率为44.8%。 Gartner预计到2028年&#xff0c;至少15%的日常工作决策将由AI Agent自主完成&#xff0c;AI Agent在企业应用中…

第 32 章 - Elasticsearch 的应用场景与技术解决方案

思维导图 0. 简介 Elasticsearch 主要应用于搜索场景。场景的如 应用内的搜索框、还有日志搜索等。 下面将介绍 Elasticsearch 在开发中的常见应用场景。 1. 日志搜索 日志搜索是最常见的应用。 其组合技术为&#xff1a;Kafka、Logstash、Elasticsearch、Kibana 该组合整体…

VsCode对Arduino的开发配置

ps&#xff1a;我的情况是在对esp32进行编译、烧录时&#xff0c;找不到按钮&#xff0c;无法识别Arduino文件&#xff0c;适合已经有ini文件的情况。 1.在vscode中安装拓展 2.打开设置&#xff0c;点击右上角&#xff0c;转到settings.json文件 3.复制以下代码并保存 {"…

python学opencv|读取图像(三十二)使用cv2.getPerspectiveTransform()函数制作透视图-变形的喵喵

【1】引言 前序已经对图像展开了平移、旋转缩放和倾斜拉伸技巧探索&#xff0c;相关链接为&#xff1a; python学opencv|读取图像&#xff08;二十八&#xff09;使用cv2.warpAffine&#xff08;&#xff09;函数平移图像-CSDN博客 python学opencv|读取图像&#xff08;二十…

AWS云计算概览(自用留存,整理中)

目录 一、云概念概览 &#xff08;1&#xff09;云计算简介 &#xff08;2&#xff09;云计算6大优势 &#xff08;3&#xff09;web服务 &#xff08;4&#xff09;AWS云采用框架&#xff08;AWS CAF&#xff09; 二、云经济学 & 账单 &#xff08;1&#xff09;定…

Unity TextMesh Pro入门

概述 TextMesh Pro是Unity提供的一组工具&#xff0c;用于创建2D和3D文本。与Unity的UI文本和Text Mesh系统相比&#xff0c;TextMesh Pro提供了更好的文本格式控制和布局管理功能。 本文介绍了TMP_Text组件和Tmp字体资产(如何创建字体资产和如何解决缺字问题),还有一些高级功…

数据结构与算法之链表: LeetCode 19. 删除链表的倒数第 N 个结点 (Ts版)

删除链表的倒数第 N 个结点 https://leetcode.cn/problems/remove-nth-node-from-end-of-list/ 描述 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示…

【STM32-学习笔记-2-】外部中断

文章目录 外部中断Ⅰ、EXIT函数Ⅱ、EXTI_InitTypeDef结构体参数①、EXTI_Line②、EXTI_LineCmd③、EXTI_Mode④、EXTI_Trigger Ⅲ、NVIC函数Ⅳ、NVIC_InitTypeDef结构体参数①、NVIC_IRQChannel②、NVIC_IRQChannelCmd③、NVIC_IRQChannelPreemptionPriority④、NVIC_IRQChanne…

利用 awk 定制化处理大量数据的计算

问题 有上万行&#xff08;甚至更多&#xff09;不断递增的浮点数&#xff08;每行一个&#xff09;&#xff0c;怎么将它们每四个一组计算每组第四个和第一个之间的差值&#xff0c;并打印输出计算结果&#xff1f; 例如文件 data 有以下数据&#xff1a; 2.699350 2.69935…

llama.cpp 模型可视化工具 GGUF Visualizer

llama.cpp 模型可视化工具 GGUF Visualizer 1. GGUF Visualizer for VS Code (gguf-viz)1.1. Features1.2. Extension Settings References GGUF Visualizer https://marketplace.visualstudio.com/items?itemNameAgainstEntropy.gguf-viz 1. GGUF Visualizer for VS Code (g…

10,STL——list类

一&#xff0c;list类的介绍和使用 1&#xff0c;了解list类 1. &#xff09;list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. &#xff09;list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关…