【Linux】浅谈文件原理与操作

news2024/11/17 10:04:47

目录

问题引入

浅谈文件原理

文件操作

文件的打开与关闭

open

close

write与read

再谈C库文件操作


问题引入

🌸以前我们学过C语言的文件操作,而不同语言的文件操作都是不一样的,我们该如何理解这一现象,能不能用一种统一的视角看待所有文件操作?今天就一起来谈谈文件操作。


浅谈文件原理

我们都知道,文件 = 内容 + 属性,对于一个文件的操作可以看成对内容或属性的操作

通过冯诺依曼体系我们知道当我们对文件进行操作时,该文件一定处于内存之中,而未被进行操作的文件则位于磁盘里。

在操作系统看来,文件便可以被分成两大类:磁盘文件被打开文件

🌸其中被打开文件至少需要将文件属性加载到内存之中,而每次文件操作前我们都要先打开文件的本质就是:将目标文件属性加载到内存中。因此,OS内部一定会同时存在大量的被打开的文件。需要将其以先描述再组织的方式管理起来

这样在OS内部对于打开文件的管理就转换成了对链表的增删查改。即文件被打开前,OS要为被打开文件创建内核数据结构 struct file

🌸那么文件是被谁打开的呢?

  • 用户通过调用进程完成打开文件的操作

如此解释后,我们对于文件又有进一步的认识,下面我们来介绍一下在OS层面文件操作的系统接口。

文件操作

🌸对C语言文件操作不熟悉或有些忘记了的,也可以看看这篇复习一下:C语言文件操作的基础应用。

文件的打开与关闭

open

🌸通过手册查询,我们可以找到 open 函数的相关信息,其中的参数分别是文件路径打开文件的选项

🌸其中的 flag ,我们不能将其看成一个整数而是将其看作一个位图

🌸其中每一个位置都代表一个选项,为 1 则表示选中反之不选,库中定义了宏方便我们直接使用。

  • O_WRONLY  只写选项
  • O_RDONLY   只读选项
  • O_APPEND   追加写入
  • O_TRUNC     打开时清空文件
  • O_CREAT      若文件不存在则创建
  • O_RDWR       支持同时读写

🌸在使用时使用 | 操作符标记位图的对应位置即可。

int main()
{
    open("log.txt", O_WRONLY | O_TRUNC | O_CREAT);  //以只读每次打开清空文件若不存在则创建新文件的方式打开
    return 0;
}

🌸这时候,我们便会发现现在的这个操作跟 fopen 十分的相似,只不过将 w 选项拆成了三个选项。其实,fopen 的底层便是调用了这个系统调用进行文件的打开操作。

🌸虽然我们成功创建出一个文件了,但此时我们可以看到,该文件的权限却是乱码,因此在创建文件时我们就需要手动设置文件的权限。

🌸open 还重载了三个参数的版本,供我们设置文件权限

int main()
{
    open("log.txt", O_WRONLY | O_TRUNC | O_CREAT,0666);
    return 0;
}

 

🌸这下创建出来的就是正常权限的文件了,但是却与我们设置的 0666 不一样而是 0664 呢?这是由于文件的权限还受到权限掩码的影响,因此需要将 umask 置零。

int main()
{
    umask(0);
    open("log.txt", O_WRONLY | O_TRUNC | O_CREAT,0666);
    return 0;
}

🌸这下就根据我们要求创建出对应权限的文件了。

🌸而  open 有一个返回值,我们刚才忽略掉了,其为文件描述符又名 fd,我们需要定义一个变量接收一下它,之后需要用它定位文件。

🌸若 fd 为 -1 说明打开文件失败,我们可以在打开文件后增加一个判断。

int main()
{
    umask(0);
    int fd = open("log.txt", O_WRONLY | O_TRUNC | O_CREAT,0666);
    if(fd == -1)
    {
        printf("fd: %d,errstring is: %s\n",fd,strerror(errno));
    }
    return 0;
}

close

🌸关闭文件就需要我们上面存起来的 fd 了,直接传入 fd 即可关闭文件。

int main()
{
    umask(0);
    int fd = open("log.txt", O_WRONLY | O_TRUNC | O_CREAT,0666);
    if(fd == -1)
    {
        printf("fd: %d,errstring is: %s\n",fd,strerror(errno));
    }
    close(fd);
    return 0;
}

write与read

🌸打开文件后我们就可以根据需求对文件进行读写了,先介绍 write 接口。

🌸参数分别是 fd写入内容的字符串写入的字节数,写入后返回写入的字节数,失败则返回 -1。

🌸这里我先将用 snprintf 内容格式化写入一个字符串中,再写到文件里。

int main()
{
    umask(0);
    int fd = open("log.txt", O_WRONLY | O_TRUNC | O_CREAT,0666);
    if(fd == -1)
    {
        printf("fd: %d,errstring is: %s\n",fd,strerror(errno));
    }
    const char* ptr = "helloworld";       //原字符串
    char str[20];                         //转接的字符数组
    int i = 1;
    snprintf(str,sizeof(str),"%s: %d",ptr,i);   //加个序号格式化写入
    write(fd,str,strlen(str));                  //写入文件
    close(fd);                                  //关闭文件
    return 0;
}

[注意]:\0 是C语言库中的设定,直接写入到文件中会被识别成乱码,使用 write 写入时要注意不写入 \0。因此写入时直接使用 strlen 便可以自动规避掉 \0。

🌸之后我们来看读取的操作,需要传入 fd 定位文件,之后将文件内的数据读入数组中,读取 count 个字节。

🌸成功读取后会返回读取的字节数,若读取失败则会返回 -1。

🌸这次我们以读取的方式打开文件,由于不用创建文件因此就不需要手动设置文件权限了。

int main()
{
    int fd = open("log.txt", O_RDONLY);     //只读打开文件
    char buffer[1024];
    size_t n = read(fd, buffer, sizeof(buffer) - 1);   //为\0留一个位置
    if (n > 0)      //说明读入数据
    {
        buffer[n] = '\0';            //在数据尾部插入\0
        printf("%s\n", buffer);      //打印出数据内容
    }
    return 0;
}

🌸同时为了方便接下来的读写,读取需要为 \0 预留一个位置,之后再加上即可。

再谈C库文件操作

🌸在上面我们就说过C库文件操作的底层本质上也是调用了操作系统提供的系统调用,即库函数只是对系统调用的封装

🌸那又是为什么呢?我们可以用下面这张图简单理清几者之间的关系。

🌸只要涉及文件操作,就与文件读写分不开关系,在读写的过程中便会涉及到对硬件的访问,而硬件是由操作系统进行管理的。因此从用户层面出发,只要访问到硬件就无法绕开操作系统。

🌸不仅只是C语言,任何语言的文件操作都是对系统调用的封装,都是借助系统接口才能够实现!!!


🌸好了,今天 浅谈文件原理与操作 的相关内容到这里就结束了,如果这篇文章对你有用的话还请留下你的三连加关注。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

有关 string 类的练习(下)

目录 一、反转字符串 II 二、反转字符串中的单词 III 三、找出字符串中第一个只出现一次的字符 四、字符串相乘 五、把字符串转换成整数 一、反转字符串 II 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转…

Spring,注解开发

Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架 1、组成 spring七大模块详解 2、IOC理论推导 传统的开发 (pojo层、DAO层和业务层) (1)UserDao (2) UserDaoImpl (3)…

天狼星-大熊座 Ursa Major SIRIUS

大熊座 Ursa Major SIRIUS 键盘说明 客制化键盘: 大熊座 Ursa Major SIRIUS 配列: 75 键帽:KCA-HelloWorld-Black 双模: 蓝牙-分裂方案 驱动配置:Link Lab 驱动设置软件 键盘操作 键盘说明参考:键位配…

利用WinDbg查看堆栈中方法入参的值4(C#)

由于作者水平有限,如有写得不对的地方,请指正。 使用WinDbg的过程中,坑特别的多,对版本要求比较严格,如: 1 32位应用程序导出的Dump文件要用32位的WinDbg打开,想要没有那么多的问题&#xf…

海底光缆位置探测技术的应用概述

1. 概述 海底光缆运行在地质环境复杂的海洋环境中,地震、海床塌陷、滑坡、洋流变化、海洋生物及船只抛锚都有可能造成光缆断裂、破损,影响光缆的安全运行。海底光缆一旦遭受损坏,其造成的经济损失无法估量。因此在海洋开发工程实施前&#xf…

Web转化为APP——YonBIP(APICloud迁移版)

目录 平台注册 平台使用 设计封面(端设置) APP证书 代码上传 移动打包 运营管理和移动插件 众所周知,APP开发是一件非常麻烦的事,很多擅长Web开发的人未必擅长APP开发。那么作为一个Web开发者,可不可以有很方便…

基于prefix tuning + Bert的标题党分类器

文章目录 背景一、Prefix-Tuning介绍二、分类三、效果四、参阅 背景 近期, CSDN博客推荐流的标题党博客又多了起来, 先前的基于TextCNN版本的分类模型在语义理解上能力有限, 于是, 便使用的更大的模型来优化, 最终准确率达到了93.7%, 还不错吧. 一、Prefix-Tuning介绍 传统的…

Redis之Redisson原理详解

文章目录 1 Redisson1.1 简介1.2 与其他客户端比较1.3 操作使用1.3.1 pom.xml1.3.2 配置1.3.3 启用分布式锁 1.4 大致操作原理1.5 RLock1.5.1 RLock如何加锁1.5.2 解锁消息1.5.3 锁续约1.5.4 流程概括 1.6 公平锁1.6.1 java中公平锁1.6.2 RedissonFairLock1.6.3 公平锁加锁步骤…

50 Projects 50 Days - Form Input Wave 学习记录

项目地址 Form Input Wave 展示效果 Form Input Wave 实现思路 简单的登陆界面结构,只是在输入框聚焦时标题提示文字会有一个字母逐渐向上跳动的动画效果,这需要针对每个字符单独设置变换的延时,可以考虑在JavaScript中处理这部分逻辑&am…

2017~2018学年《信息安全》考试试题(A1卷)

北京信息科技大学 2017 ~2018 学年第二学期《信息安全》考试试题 (A 卷) 课程所在学院:计算机学院 适用专业班级:计科 1504-6、重修 考试形式:闭卷 一、单选题(本题满分 20 分,共含 10 道小题,每小题 2 分) 网络安全是指网络系统的硬件、软件及( C )的…

【头歌-Python】Python第九章作业(初级)第5关

第5关:绘制程序设计语言饼图 任务描述 列表labels和sizes中的数据分别是目前主流程序设计语言及其热度数据(百分比),请根据这些数据绘制饼图,并将Python程序设计语言所在区域突出0.1显示。 labels [C语言, Python…

Java ~ Reference ~ ReferenceQueue【总结】

前言 文章 相关系列:《Java ~ Reference【目录】》(持续更新)相关系列:《Java ~ Reference ~ ReferenceQueue【源码】》(学习过程/多有漏误/仅作参考/不再更新)相关系列:《Java ~ Reference ~ …

一篇就能学懂的散列表,让哈希表数据结构大放光彩

目录 1.散列表的基本概念 2.散列表的查找 3.散列函数的构造方法 1.直接定址法 2.除留余数法 4.散列表解决冲突的方法 1.开放定址法 2.链地址法 1.散列表的基本概念 基本思想:记录的存储位置与关键字之间存在的对应关系 对应关系——hash函数 Loc(i) H(k…

关于外包被开要怎么维护自己的权益

我一直以为外包被开都是没有任何赔偿的,之前网上对于外包的消息都是说,没有任何赔偿或者是怕麻烦然后就干脆放弃了的各种评论。。。但是最近我在问到一个朋友的时候,他很好的维护了自己的权益。最后获得了N1 保留证据 当被告知外包需要你离场…

牛客网语法篇刷题(C语言) — 运算

作者主页:paper jie的博客_CSDN博客-C语言,算法详解领域博主 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于《C语言-语法篇》专栏,本专栏是针对于大学生,编程小白…

单链表OJ题:LeetCode--138.复制带随即指针的链表

朋友们、伙计们,我们又见面了,本期来给大家解读一下LeetCode中第138道单链表OJ题,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! 数据结构与算法专栏:数据结构与算法 个 人…

python使用Faker库进行生成模拟mock数据(基本使用+五个小案例)

使用faker进行生成模拟(mock))数据 文章目录 使用faker进行生成模拟(mock))数据一、Faker库安装二、Faker库基本介绍三、案例1:Faker库生成核酸数据四、案例2:生成不重复的人名和地名五、案例3:生成有时间期限的低保数据六、案例4&#xff1a…

01-Vue 项目环境搭建和创建准备工作

一. 学习目标 掌握 Vue 项目创建的依赖环境掌握 Vue 项目创建过程 二. 学习内容 掌握搭建 Vue 项目准备环境掌握 Vue 项目创建过程了解 Vue 项目各子目录 三. 学习过程 1. 准备工作 (1)安装Node.js 打开node.js官网:Node.js &#xff0…

【状态估计】无迹卡尔曼滤波(UKF)应用于FitzHugh-Nagumo神经元动力学研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

详解ASP.NET Core 在 IIS 下的两种部署模式

KestrelServer最大的优势体现在它的跨平台的能力,如果ASP.NET CORE应用只需要部署在Windows环境下,IIS也是不错的选择。ASP.NET CORE应用针对IIS具有两种部署模式,它们都依赖于一个IIS针对ASP.NET CORE Core的扩展模块。 一、ASP.NET CORE C…