当前位置: 首页 > news >正文

【文件fd】回顾C语言文件操作 | 详细解析C语言文件操作写w追加a | 重定向和“w““a“

目录

前言

回顾C语言的操作

Q1

Q2 

Q3 

C语言文件操作

w方式

a方式

重定向和"w""a"方式


前言

前面进程虚拟地址空间让我们对进程的理解更加深入。在基础IO我们会详细介绍文件和文件系统。本专题的核心内容是文件。

  • 深刻理解文件(站在OS的角度)
  • 深入理解重定向和缓冲区
  • 学习文件系统(磁盘文件和经典的文件系统结构)
  • 以及动静态库制作和使用,yum源的配置等操作。

回顾C语言的操作

❓在C语言阶段,我们学习了C语言是如何打开/关闭/写入/读取文件的。我们仅仅是在语言层面上学会了对文件的操作接口。不仅C/C++/Java等其他语言都有文件操作接口,文件操作都不一样,为什么不一样。

❓是否我们站在OS的角度就可以理解文件。

请看以下代码☞,思考下面问题: 

 1: testfile.c                                                                               1 #include<stdio.h>2 int main()3 {4   FILE *fd = fopen("log.txt","w");                                                                           5   if(fd == NULL)6   {7     perror("fopen");8     return 1;9   }10   fclose(fd);11   return 0;12 }//运行可执行程序,文件不存在,OS默认创建在当前目录下

【文件指针FILE】  

【perror】

Q1

❓创建一份C语言的文件时,并没有指明文件的具体路径,代码中只是告知文件名,OS怎么知道当前创建的文件在我们想要的路径下呢。

回答:因为我们在运行我们的程序的时候,执行打开文件操作的代码的时候。 程序已经变成一个进程。所以我们创建log.txt文件时,默认会结合当前进程所在路径创建,所以如何没有路径给到OS,那么OS会结合进程当前所在路径去创建log.txt。 

❓我们写完文件操作的代码,fopen文件就算被打开了吗。

回答:文件操作的代码写完了。但是不编译运行。文件根本没有被打开。我们要进行文件操作,前提是我们的程序跑起来了,成为进程了。文件打开和关闭,是CPU在调度我们的进程,正好执行到fopen和fclose代码。打开文件的本质其实是进程打开文件!!

【进程在启动时所处的路径叫进程的当前工作路径】

Q2 

❓文件没有被打开的时候在哪里。在磁盘上

❓一个进程能打开很多文件吗。可以

❓系统中能存在很多进程吗。很多情况下,在OS内部,一定存在大量的被打开的文件。

❓OS需要对大量的文件做管理吗。肯定的。

没有被打开的文件在磁盘(硬件上),如果需要打开文件,就需要访问硬件。硬件的管理者是操作系统。一定是OS打开文件。OS打开大量的文件,就需要把这些打开的文件进行管理。(管理的六字真言:先描述再组织)

❓先描述再组织。意味着:在OS内部,也要创建文件对应对象-内核数据结构,打开文件,创建数据结构,形成很多文件对象。最后以链表的形式管理起来。对文件的管理,变成对链表的增删查改。(每一个被打开的文件,在OS内部,一定要存在对应的描述文件属性的结构体。类似PCB)

  • struct PCB(task_struct):可执行程序加载到内存中,可执行程序的内核数据结构
  • struct RunQueue:硬件有对应的等待队列
  • struct file:文件也有对应的内核数据结构(存放文件属性)
  • OS内核中一个被打开的文件本质一定是一个文件对象或者一个结构体类型的对象。
  • struct task_struct☞struct file两种对象之间的指针关系 

Q3 

 ❓新建一个大小为0的文件在磁盘需不需要占据磁盘空间。(文件没有打开,没有在内存中,在磁盘中)

回答:要占磁盘空间。文件名/时间/类型/大小/权限等文件属性等都是数据,需要占据磁盘空间。文件 = 文件属性 + 文件内容

C语言文件操作

w方式

以w方式打开文件。

  • w方式的特点:
  1. 文件存在,就清空写入
  2. 文件不存在,在当前进程的工作目录路径下创建,写入。
  3. 默认打开文件的时候,就会先把目标文件清空!
  • 写入库函数接口:fprintf
  • man fprintf
  • int fprintf(FILE *stream, const char *format, ...);
  • FILE *stream:写入指定的文件
  • const char *format, ...:以指定格式把指定内容写入
  • w      Truncate  file  to zero length or create text file for writing.

打开创建当前文件。进程被调度,执行到代码语句的时候,才会打开,写入,判断,关闭等系列文件操作(进程被调度)。里面含有/proc进程的当前工作路径。

 【文件存在,就清空写入】

【清空实验】

在存在log.txt文件且log.txt内容存在的情况下。只有打开,没有写入和关闭。我们再以w的方式打开一次文件。

原log.txt存在数据,但再以写的方式打开一次(只打开)。文件仍然存在,默认文件的内容被清空。在C语言,以w属性打开文件,文件打开即清空。

【文件不存在,在当前进程的工作目录路径下创建,写入】

a方式

以a方式打开文件。

  • a方式的特点:
  1. 文件存在,就不清空写入
  2. 文件不存在,在当前进程的工作目录路径下创建,写入。
  3. 默认打开文件的时候,就不会先把目标文件清空!
  • 文件存在且有内容的情况下,重新打开文件,写入。w方式一定会清空文件再写入;而a方式不会清空直接追加。
  • appending追加:追加的本质也是写到文件的结尾。

 【文件存在,就清空写入】

【文件不存在,在当前进程的工作目录路径下创建,写入】 

重定向和"w""a"方式

重定向回顾:

使用重定向可以极大地提高Linux命令行操作的灵活性和效率,尤其是在脚本编写和自动化任务中。

 请看下面代码☞:

  • echo "hello linux" Linux当中一切皆文件默认向显示器文件stdout打印
  • > 输出重定向本质就是把向显示器文件写入的数据,重定向向log.txt文件写入
  • 经过重定向变成了本来应该向显示器打印的内容,写入了磁盘文件中
  • 经过上面分析,我们猜测重定向一定伴随文件操作或者和文件操作有关。
  • 输出重定向一定是文件操作!

  • > 的特点:每次写入文件的数据都是存在文件,清空写入;不存在,创建写入。(每次写入都要清空)
  • 所以,推测> 是以 "w" 方式把文件打开。
  • > 可以用来新建文件,清空文件。(不存在就创建。先清空,再写入)
  • >> 的特点:存在文件,不清空写入;不存在,创建写入。
  • 所以,推测>> 是以"a"方式把文件打开。

【>】 

【>>】

🙂感谢大家的阅读,若有错误和不足,欢迎指正。

相关文章:

  • HOW - BFF 服务实践系列(一)
  • 探索Python机器学习:从基础到实践
  • Java基础入门day62
  • 【云原生】Kubernetes----POD控制器
  • 编程学习技巧——实战
  • 对boot项目拆分成cloud项目的笔记
  • 如何实现一个AI聊天功能
  • 智能超越了科技,更是一个复杂系统
  • 2024年5月31日 (周五) 叶子游戏新闻
  • Linux学习笔记(清晰且清爽)
  • Streamsets-JDBC模式使用更新时间字段数据同步
  • 6/1 第十五届蓝桥杯国赛pb组 真题本人答案 仅供参考
  • AJAX基础知识
  • Java大厂面试题第2季
  • Vue使用axios实现调用后端接口
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • CSS居中完全指南——构建CSS居中决策树
  • extjs4学习之配置
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Protobuf3语言指南
  • use Google search engine
  • Vue官网教程学习过程中值得记录的一些事情
  • 百度小程序遇到的问题
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 第十八天-企业应用架构模式-基本模式
  • 基于 Babel 的 npm 包最小化设置
  • 基于web的全景—— Pannellum小试
  • 简单基于spring的redis配置(单机和集群模式)
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 普通函数和构造函数的区别
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 微信小程序开发问题汇总
  • 携程小程序初体验
  • 用Visual Studio开发以太坊智能合约
  • 栈实现走出迷宫(C++)
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​MySQL主从复制一致性检测
  • #单片机(TB6600驱动42步进电机)
  • $().each和$.each的区别
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (编译到47%失败)to be deleted
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (十一)图像的罗伯特梯度锐化
  • (算法二)滑动窗口
  • (一)WLAN定义和基本架构转
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET 命令行参数包含应用程序路径吗?
  • .net 托管代码与非托管代码
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .NET开源项目介绍及资源推荐:数据持久层