目录

  • 前言
  • 一、核心概念:
  • 二、关键操作步骤:
  • 三、为什么需要文件IO?
  • 四、常见类型:
  • 五、标准IO源码
  • 六、笔试真题和练习
    • 1.
      • 代码实现1
      • 代码实现2
    • 2.
      • 代码实现
    • 3.
      • 代码实现
  • 4.
      • 代码实现
  • 5.
      • 代码实现
  • 七、总结

前言

文件IO(文件输入/输出) 是指计算机程序与外部存储设备(如硬盘、SSD、U盘等)上的文件进行数据交换的过程。简单来说,就是程序从文件中读取数据(Input)或将数据写入文件(Output)。文件IO这个板块我们会学习很多个接口,所以说我们长时间不用就会忘记,一定要会用man指令查手册,必须要回看得懂源码。

在这里插入图片描述

一、核心概念:

文件(File):
存储在持久化介质(如硬盘)上的数据集合,具有名称和路径。可以是文本、图片、音频、程序等任何形式。

输入(Input)
程序从文件读取数据到内存(如变量、数据结构)。例如:读取配置文件、加载图片数据。

输出(Output):
程序将内存中的数据写入文件。例如:保存用户设置、导出计算结果。

二、关键操作步骤:

打开文件(Open):
建立程序与文件的连接,指定操作模式(读、写、追加等)。

读写数据(Read/Write):

**读:**将文件内容传输到程序内存。

**写:**将程序内存中的数据写入文件。

关闭文件(Close):
释放资源,确保数据完整保存(重要!未关闭可能导致数据丢失)。

三、为什么需要文件IO?

**持久化存储:**内存数据在程序关闭后消失,文件可长期保存。

**数据共享:**不同程序或用户可通过文件交换数据。

**处理大数据:**内存有限,文件可分批读取/写入海量数据。

四、常见类型:

**文本文件IO:**处理字符数据(如 .txt, .csv),需注意编码(UTF-8等)。

**二进制文件IO:**直接处理字节(如图片 .jpg、可执行程序),无编码转换。

五、标准IO源码

因为标准IO的接口都是在Linux的man手册的第3长,在Linux系统输入man 3 fopenman 3 fread,等常用的函数接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

六、笔试真题和练习

1.

请添加图片描述

代码实现1

这次我用的是fopen打开文件,fclose关闭文件,fgetc一个一个字符读取文件中的内容,所以光标会自己向后偏移。

#include <stdio.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{if(argc != 2){printf("argument is invailed!\n");exit(1);}FILE* file = fopen(argv[1], "rb");if(!file){printf("file open failed!\n");exit(1);}int cnt = 0;while(1){if(fgetc(file) == EOF){break;}cnt++;}printf("file %s size is %d byte\n",argv[1],cnt);fclose(file);return 0;
}

代码实现2

这个代码是利用fseek函数将文件的光标移动到文件末尾,然后用ftell函数记录当前光标位置到文件开头的偏移值。

#include <stdio.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{if(argc != 2){printf("argument is invailed!\n");exit(1);}FILE* file = fopen(argv[1], "rb");if(!file){printf("file open failed!\n");exit(1);}fseek(file,0,SEEK_END);printf("file %s size is %ld byte\n",argv[1], ftell(file));fclose(file);return 0;
}

2.

在这里插入图片描述### 代码实现
用到了fread和fwrite接口,定义一个缓冲区(buffer),记录读写次数,每次读写前把缓冲区清空。

代码实现

/** Copyright (c)* * date: 2025-7-22* * author: Charles* * function name : copyFile** function: 把一个文件的所有内容拷贝到另一个文件*/#include <stdio.h>
#include <stdlib.h>
#include <strings.h>#define BUFFERSIZE 512int main(int argc, char const *argv[])
{long file_src_size = 0; 		//源文件的总字节数long remainder = 0; 			//总字节数与缓冲区字节数的余数int  cnt = 0;					//用源文件总字节数除以缓冲区字节数,也就是再循环里的读写次数long file_des_size = 0;         //目标文件的总字节数char buffer[BUFFERSIZE] = {0};	//缓冲区if(argc != 3){printf("argument is invailed!\n");exit(1);}FILE* file_src = fopen(argv[1], "rb");FILE* file_des = fopen(argv[2], "wb");if(!file_src || !file_des){printf("file open failed!\n");exit(1);}fseek(file_src, 0, SEEK_END);file_src_size = ftell(file_src);fseek(file_src, 0, SEEK_SET);printf("file_src [%s] size is [%ld] byte\n",argv[1], file_src_size);cnt = file_src_size / BUFFERSIZE;remainder = file_src_size % BUFFERSIZE;while(cnt--){memset(buffer, 0, BUFFERSIZE);size_t n = fread(buffer, 1, BUFFERSIZE, file_src);fwrite(buffer, 1, n, file_des);}if(remainder){memset(buffer, 0, BUFFERSIZE);size_t n = fread(buffer, 1, remainder, file_src);fwrite(buffer, 1, n, file_des);}fseek(file_des, 0, SEEK_END);file_des_size = ftell(file_des);fseek(file_des, 0, SEEK_SET);printf("file_des [%s] size is [%ld] byte\n",argv[2], file_des_size);fclose(file_src);fclose(file_des);return 0;
}

3.

请添加图片描述

代码实现

在一个循环里用open函数,记录直到函数返回值为-1为止。

/** Copyright (c)* * date: 2025-7-22* * author: Charles* * function name : FileOpenCount** function: 测试文件打开次数*/#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define BUFFERSIZE 512int main(int argc, char const *argv[])
{if(argv != 2){printf("argument is invailed!\n");exit(1);}int cnt = 0;while(open(argv[1], O_RDWR) != -1){cnt++;}printf("file can be open %d count!\n",cnt + 3);//为什么加3,因为在打开这个文件的时候系统会自动打开标准输入,标准输出,错误这个文件return 0;
}

4.

请添加图片描述

像这个获取时间的api,都是系统IO。

代码实现

/** Copyright (c)* * date: 2025-7-23* * author: Charles* * function name : time_log.c** function: 每秒钟打印当前日期到log.txt文件中*/#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>int main(int argc, char const *argv[])
{while(1){time_t t = time(NULL);struct tm *tm_info = localtime(&t);char day[8][20] = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};char buffer[256];snprintf(buffer,sizeof(buffer),"%d年%02d月%02d日 %s %02d:%02d:%02d",tm_info->tm_year + 1900,tm_info->tm_mon + 1,tm_info->tm_mday,day[tm_info->tm_wday],tm_info->tm_hour,tm_info->tm_min,tm_info->tm_sec);FILE* file = fopen("./log.txt","a");if(!file){perror("fopen");exit(-1);}fputs(buffer, file);fclose(file);sleep(1);}return 0;
}

5.

请添加图片描述
这题可以看看bmp的文件存储格式图。然后要注意的是系统默认会有一个对齐机制,就比如说bmp_header这个结构体如果取消对齐大小为14字节,如果不取消大小就为16字节。
请添加图片描述

代码实现

/** Copyright (c)* * date: 2025-7-23* * author: Charles* * function name : getBMP.c** function: 获取bmp图片大小,像素宽度和高度信息*/#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>#pragma  pack(1) 	//取消字节对齐struct bmp_header{char s[2];int size;short a;short b;int c;
};struct bmp_info{int a;int width;int heigth;short a1;short b1;int off1;int off2;int off3;int off4;int off5;int off6;
};#pragma  pack(0)int main(int argc, char const *argv[])
{// int bmp_size = 0;		//bmp图片的总字节数// int bmp_width = 0;		//bmp图片的像素宽度// int bmp_heigth = 0;		//bmp图片的像素高度if(argc != 2){			//参数错误处理printf("argument fail! \n");exit(-1);}int bmp_fd = open(argv[1], O_RDWR);if(bmp_fd == -1){printf("open file : %s fail\n", argv[1]);exit(-1);}// char header[2] = {0};// read(bmp_fd, header, 2);struct bmp_header bh;struct bmp_info bi;read(bmp_fd, &bh, 14);read(bmp_fd, &bi, 40);if(bh.s[0] != 'B' || bh.s[1] != 'M'){		//判断写入的两个字符是否是BM开头的printf("open file not bmp\n");exit(-1);}printf("bmp size is %d byte\n", bh.size);printf("bmp width is %d px\n", bi.width);printf("bmp heigth is %d py\n", bi.heigth);// lseek(bmp_fd, 2, SEEK_SET);// read(bmp_fd, &bmp_size, 4);// printf("bmp size is %d byte\n", bmp_size);// lseek(bmp_fd, 18, SEEK_SET);// read(bmp_fd, &bmp_width, 4);// printf("bmp width is %d byte\n", bmp_width);// lseek(bmp_fd, 18 + 4, SEEK_SET);// read(bmp_fd, &bmp_heigth, 4);// printf("bmp heigth is %d byte\n", bmp_heigth);close(bmp_fd);return 0;
}

七、总结

文件IO是程序与外部存储交互的桥梁,通过 读取(Input) 和 写入(Output) 实现数据的持久化和重用,是几乎所有软件的基础功能。不同编程语言有各自的API(如C的 fopen/fread、Java的 FileInputStream、Python的 open()),但核心逻辑一致。

在这里插入图片描述

希望各位靓仔靓女点赞,收藏,关注多多支持,我们共同进步,后续我会更新更多的面试真题,你们的支持将是我前进最大的动力。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习 5:DFT

DFT技术 DFT &#xff08;design for testability&#xff09;&#xff1a;指在设计系统和电路的同时&#xff0c;考虑测试的需求&#xff0c;通过增加一定的硬件开销&#xff0c;获得最大可测性的设计过程。&#xff08;因为增加了硬件&#xff0c;所以也带来了不足&#xff…

最长递增子序列(LIS)问题详解

最长递增子序列LIS问题详解一、问题定义与核心特征1.1 问题描述1.2 核心特征二、基础解法&#xff1a;动态规划&#xff08;DP&#xff09;2.1 解法思路2.2 Java代码实现2.3 复杂度分析三、优化解法&#xff1a;二分查找贪心3.1 核心思路3.2 二分查找的作用3.3 Java代码实现代码…

什么是HTTP长连接、短连接?谁更能抗DoS攻击?

想象你在快餐店点餐&#xff1a; 你&#xff1a;“一个汉堡”收银员&#xff1a;“好的&#xff0c;15元”交易结束&#xff0c;你离开队伍你想加杯可乐&#xff0c;重新排队你&#xff1a;“一杯可乐”收银员&#xff1a;“好的&#xff0c;8元”再次离开… 这种每次沟通后立即…

微软徽标认证是什么?如何快速获取驱动签名?

在Windows系统中安装硬件驱动时&#xff0c;是否遇到过“无法验证发布者”的警告&#xff1f;这正是驱动数字签名在背后发挥作用。对于软件开发者而言&#xff0c;驱动数字签名不仅是系统兼容性的保障&#xff0c;更是企业品牌信任度的核心。一、驱动数字签名的核心作用驱动数字…

Apache Ignite缓存基本操作

这段内容主要讲解了 Apache Ignite 中缓存&#xff08;IgniteCache&#xff09;的基本操作&#xff0c;包括获取缓存、创建缓存、销毁缓存、执行原子操作以及异步操作等。下面我将用中文对这些内容进行详细解释&#xff0c;帮助你更好地理解。一、获取缓存实例&#xff08;Gett…

最新基于R语言结构方程模型分析与实践技术应用

现代统计学理论和方法的不断完善&#xff0c;使科研工作对统计方法的要求也越来越高&#xff0c;面对纷繁复杂的数据&#xff0c;如何选择最为合适的数据分析方法已成为科研工作者&#xff0c;尤其是广大刚处于科研生涯起步阶段的研究生们最为棘手问题。随着科学的发展&#xf…

物联网_TDengine_EMQX_性能测试

一、Tdengine接口开发文档 1、数据库 1.创建数据库 URL /dp/createdb/ method post 请求示例 {"db_name":"demo01" // 必填 }响应示例 // 成功 {"code": 1,"data": {"成功创建数据库": "demo04"},"error…

从分析到优化:Amazon Q CLI 助力 EKS 网络调用链剖析与运维实践

1. 引言 在 Amazon EKS&#xff08;Elastic Kubernetes Service&#xff09;环境中&#xff0c;理解从 ALB&#xff08;Application Load Balancer&#xff09;到 Pod 的完整网络调用链对运维人员至关重要。本文将展示如何利用 Amazon Q CLI 这一 AI 助手工具&#xff0c;通过…

Class10简洁实现

Class10简洁实现 import torch from torch import nn from d2l import torch as d2l# 输入为28*28&#xff0c;输出为10类&#xff0c;第1、2隐藏层256神经元 num_inputs, num_outputs, num_hiddens1, num_hiddens2 784, 10, 256, 256 # 第1个隐藏层丢弃率为0.2&#xff0c;第…

【多线程篇22】:ConcurrentHashMap的并发安全原理剖析

文章目录一、HashMap 的“不安全”&#xff1a;问题的根源1. 数据结构回顾 (JDK 1.8)2. 并发下的致命缺陷&#xff1a;put 操作二、ConcurrentHashMap 的安全之道 (JDK 1.8)1. 核心数据结构2. 安全的 put 操作&#xff1a;分场景精细化加锁3. 安全的 size() 计算&#xff1a;并…

【Java + Vue 实现图片上传后 导出图片及Excel 并压缩为zip压缩包】

系统环境&#xff1a; Java JDK&#xff1a;1.8.0_202 Node.js&#xff1a;v12.2.0 Npm&#xff1a;6.9.0 Java后端实现 Controller /*** xxxx-导出* param response 返回信息体* param files 上传的图片文件* param param1 参数1* param param2 参数2*/PostMapping("/ex…

安科瑞:能源微电网助力工业园区“绿色”发展

朱以真近日&#xff0c;厦门市工业和信息化局印发工业园区绿色智慧微电网建设&#xff0c;拟开展全市工业园区绿色智慧微电网试点通知&#xff0c;那么对于如何实现绿色园区的建设是今天的话题。对工业园区绿色智慧微电网建设需求&#xff0c;其核心价值体现在“源-网-荷-储-充…

VUE2 学习笔记3 v-on、事件修饰符、键盘事件

事件处理v-on用于事件交互。语法&#xff1a;v-on:要绑定的事件“事件触发时执行的函数” &#xff08;函数这里可以写括号&#xff0c;也可以不写&#xff0c;没有影响&#xff09;简写&#xff1a;:事件触发时要执行的函数&#xff0c;在Vue配置参数中&#xff0c;通过method…

变换域通讯系统CCSK的matlab仿真

CCSK&#xff08;Cyclic Code Shift Keying&#xff09;通信系统的MATLAB仿真。实现完整的CCSK调制、AWGN信道传输和解调过程&#xff0c;并计算了误码率&#xff08;BER&#xff09;。 % CCSK通信系统仿真 clear; clc; close all;% 参数设置 L 31; % m序列…

技术演进中的开发沉思-40 MFC系列:多线程协作

今天说说MFC的线程&#xff0c;当年用它实现中间件消息得心应手之时&#xff0c;可以实现一边实时接收数据&#xff0c;一边更新界面图表图文信息&#xff0c;顺滑得让人想吹声口哨。 MFC 多线程它像给程序装上了分身术&#xff0c;让原本只能 “单任务跑腿” 的代码&#xff0…

高速公路自动化安全监测主要内容

近年来&#xff0c;随着社会经济的快速发展&#xff0c;高速公路的通车里程不断增加&#xff0c;交通流量日益增大。与此同时&#xff0c;高速公路交通事故数量也呈现出一定的增长趋势。这些事故不仅造成了大量的人员伤亡和财产损失&#xff0c;还严重影响了社会的稳定和经济的…

完美解决 Ubuntu 中自定义启动器图标重复的问题(以 MATLAB 为例)

如果你在 Ubuntu 上为 MATLAB、PyCharm、Android Studio 或其他第三方应用创建了自定义启动器&#xff0c;并把它固定到了左侧的 Dock 栏&#xff0c;你很可能遇到过这个令人抓狂的场景&#xff1a; 当你满心欢喜地点击固定的图标启动程序后&#xff0c;Dock 栏上竟然“凭空”冒…

一文读懂深度模型优化器,掌握炼丹工具

深度模型优化器是训练神经网络的核心工具&#xff0c;其目标是高效地找到损失函数的最小值。从基础的随机梯度下降&#xff08;SGD&#xff09;到结合一阶动量修正与两阶段更新的Ranger&#xff0c;优化器的发展始终围绕着加速收敛、提升稳定性、适应参数差异和增强泛化能力四大…

关于虚拟机部署的k8s集群calico组件在开机恢复快照时的问题

在恢复虚拟机开机快照的时候总会出现各种的网络问题&#xff0c;连接不到自己的443端口&#xff0c;集群状态异常等等&#xff0c;绕一圈都发现不了问题&#xff0c;其实根本就没问题。虚拟机环境再现&#xff0c;恢复快照后的k8s环境&#xff0c;nfs莫名宕掉提示此报错&#x…

从感知到决策:虚拟仿真系统与视觉算法融合下的多路RTSP视频接入技术探究

1️⃣ 背景概述 随着国防信息化和智能化进程的不断加快&#xff0c;虚拟仿真系统 与 智能视觉算法平台 正逐步成为现代化装备研发、测试验证与战术训练的重要技术支撑。相比传统的静态建模或离线推演&#xff0c;新一代作战仿真与智能系统更强调 实时性、感知能力与动态交互&a…