初识Linux · 文件(1)
目录
前言:
回顾语言层面的文件
理解文件的预备知识
文件和磁盘
使用和认识系统调用函数
前言:
本文以及下篇文章,揭露的都是Linux中文件的奥秘,对于文件来说,初学Linux第一节课接触的就是文件,对于C语言,我们使用fopen可以打开文件,对于C++,我们可以使用ofstream可以打开文件,那么对于这么多打开文件的方式,难道每个不同的语言,我们都要单独去学习如何使用对应的函数吗?
当然不是,我们不妨回想最初学习的OS的结构图:

对于该结构,我们设想一个问题,文件属于哪里?
文件属于磁盘,而磁盘属于硬件,那么对于文件来说,我们能跨过OS直接操控文件吗?当然不可以,那么C语言提供的文件函数是否……?留个悬念。
现在就开始揭秘文件的神秘面纱吧!
回顾语言层面的文件
我们在C语言接触到的文件函数不知道同学们是否忘记了,如果忘记了,我们简单的回忆一下:
#include <stdio.h>
#include <stdlib.h>int main()
{FILE* fp = fopen("log.txt","w");if(fp == NULL){perror("fp");exit(1);}fclose(fp);return 0;
}
通过fopen打开文件,以w的形式对文件进行写入,对于文件操作熟悉的同学应该知道,w这个方式进行写入的话,默认是在当前目录进行写,并且,重复运行该程序,会覆盖原来的log.txt。
这是基本知识。
那么提问了:为什么系统知道要在当前目录创建文件或者是写文件呢?
这里不妨多说几句,如果我们想要在语言层面,深刻理解文件的话,是不太现实的,因为高级语言的函数肯定是和系统调用存在一定关联的,所以我们需要先回顾一下高级语言的文件操作。
那么回到最开始的问题,为什么系统知道要在当前目录创建文件呢?
我们回想,是谁运行的我们的代码?是谁打开的文件?我们?还是程序?如果是程序,程序的本质是什么?
程序的本质是进程。
所以,本质上是进程打开的我们的文件,这是第一个我们需要注意的点。
那么在Linux中,我们还有一个创建文件的方式,除了使用函数,我们可以该指令:

创建文件,这是重定向符,这是我们所熟知的,那么为什么它可以重定向呢?

以及我们第一次创建之后,写入了文件,我们再次重定向一下,文件的内容就没有了,这是为什么呢?
以及,文件是不是由OS进行统一管理呢?
如果是由OS进行统一管理,那么如果管理的呢?这里答案是比较明显的,先描述再组织。
对于这里的内容,我们都需要后面的知识作为补充来了解,所以,现在进入到预备知识部分。
理解文件的预备知识
文件和磁盘
在第一个大标题来说,我们已经知道我们使用高级语言的函数来调用OS后面的文件,那么高级语言的函数是如果调用文件的呢?
不出意外,它们是通过调用系统层面的函数来操纵文件的。所以本质来说,高级语言的文件操作函数都是通过封装系统调用的函数来实现文件操作的。
那么,我们能否直接通过系统调用,来实现文件操作呢?
使用和认识系统调用函数
先来简单的看上一段代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>int main()
{int fd = open("test.txt",O_WRONLY | O_CREAT);if(fd < 0){perror("open");exit(-1);}return 0;
}
这是系统层面的open函数,使用了两个宏O_WRONLY| O_CREAT,open函数的返回值是int等,查看文档看详细内容:

使用2号手册可以查看,2号手册也是代表的open是一个系统调用函数,并且一大堆的头文件,还是有点麻烦的,其次,open函数可以有三个函数参数,但是对于我们刚才的代码,为什么我们传的是类似于宏的|操作呢?
不卖关子,O_CREAT就是宏,其他也是,我们可以在2号手册里面查看许多宏。
对于O_WRONLY等,为什么我们要传两个宏的或操作呢?
这里提问:
void func(int a1,int a2,int a3,int a4...)
对于一个函数来说,如果参数的数目是可变的,我们不可能就一直这么写参数吧?
除了C++的可变模板参数可以解决,Linux中我们怎么解决呢?或着说,源码里面是怎么解决的?
我们看一段代码就知道了:
void Func(int a)
{if(a&&ONE)printf("ONE\n");if(a&&TWO)printf("TWO\n");if(a&&THREE)printf("THREE\n");}int main()
{Func(ONE);Func(ONE | THREE);Func(ONE | TWO);return 0;
}

那么,我们可以将printf换成其他功能,这就是源码里面的操作,其中的参数flags,就叫做标记位。
第三个参数就好说了,就是权限而已,但是呢,我们先不带权限创建了文件之后,看看权限是什么呢?

ll之后,test甚至都标红了,前面的权限呢?就变成乱码了。这是因为我们没有设置。
所以相对来说呢,两个参数的open更多是用于已经创建好的文件进行操作的。
int main()
{int fd = open("test.txt",O_WRONLY | O_CREAT,0666);if(fd < 0){perror("open");exit(-1);}return 0;
}

我们需要将原来的文件删除了之后,然后再设置即可.
但是有一个奇怪的现象,为什么test.txt的权限是664而不是666呢?相信对前文文件有所了解的话,就知道权限掩码,而系统中,存在一个函数,可以动态的修改掩码:
int main()
{umask(0);int fd = open("test.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);if(fd < 0){perror("open");exit(-1);}return 0;
}
此时权限就正常了,但是呢,系统中的掩码:
一看还是0002,难道不影响我们动态修改吗?
请记住,就近原则。
现在引入3个问题:
1. fopen的w模式,是将文件创建,如果存在,就清空。那么我们先来看看这个宏:
![]()
int main()
{umask(0);int fd = open("test.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);if(fd < 0){perror("open");exit(-1);}return 0;
}
truncate的意思就是截断,使用起来和w是一样的:

此时文件清空。
那么:
宏O_TRUNC和w模式之间的关系是什么?
2.fd的返回值有345,但是没有012,0对应的是标准输入,键盘,1和2对应的硬件都是显示器,但是1是标准输入,2是标准错误。C语言中默认打开三个流。
返回值和C语言默认打开的流的联系究竟是什么呢?
3.宏还有O_APPEND,C语言中的函数fopen的a模式代表追加,APPEND的意思也是追加。
不同的宏与不同的模式之间的联系是什么呢?
预知后事如何~请看下篇~
感谢阅读!
相关文章:
初识Linux · 文件(1)
目录 前言: 回顾语言层面的文件 理解文件的预备知识 文件和磁盘 使用和认识系统调用函数 前言: 本文以及下篇文章,揭露的都是Linux中文件的奥秘,对于文件来说,初学Linux第一节课接触的就是文件,对于C…...
【MYSQL】mysql约束---自增长约束(auto_increment)
1、概念 在Mysql中,当主键为自增长后,这个主键的值就不再需要用户输入数据了,而由数据库系统根据定义自动赋值。每增加一条记录,主键会自动以相同的步长进行增长。 注意:自增长约束通常与主键放在一起使用。 通过给…...
基于STM32设计的智能学习台灯(华为云IOT)(238)
文章目录 一、前言1.1 项目介绍【1】开发背景【2】项目实现的功能【3】项目硬件模块组成【4】ESP8266工作模式配置1.2 设计思路【1】整体设计思路【2】整体构架【3】上位机开发思路1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】摘要1.4 开发工具的选择【1…...
网络层协议 --- IP
序言 在这篇文章中我们将介绍 IP协议,经过这篇文章的学习,我们就会了解运营商到底是如何为我们提供服务的以及平时我们所说的内网,公网到底又是什么,区别是什么? IP 地址的基本概念 1. IP 地址的定义 每一个设备接入…...
Java虚拟机(JVM)介绍
**Java虚拟机(JVM)**是Java平台的核心组件,它提供了一个运行时环境,使得Java程序可以在不同的操作系统和硬件平台上运行而无需修改。 JVM的架构 JVM主要由以下几个部分组成: 类加载器(Class Loader…...
1000题-计算机网络系统概述
术语定义与其他术语的关系SDU(服务数据单元)相邻层间交换的数据单元,是服务原语的表现形式。在OSI模型中,SDU是某一层待传送和处理的数据单元,即该层接口数据的总和。 - SDU是某一层的数据集,准备传递给下一…...
Authentication Lab | IP Based Auth Bypass
关注这个靶场的其它相关笔记:Authentication Lab —— 靶场笔记合集-CSDN博客 0x01:IP Based Auth Bypass 前情提要 有些开发人员为了图方便,会给站点设置一个 IP 白名单,如果访问站点的用户的 IP 在白名单内,则允许访…...
linux中的火墙优化策略
1.火墙介绍 1. netfilter 2. iptables 3. iptables | firewalld 2.火墙管理工具切换 在rocky9 中默认使用的是 firewalld firewalld -----> iptables dnf install iptables - services - y systemctl stop firewalld systemctl disable firewalld systemctl mask fi…...
GO网络编程(三):海量用户通信系统1:登录功能初步
一、准备工作 需求分析 1)用户注册 2)用户登录 3)显示在线用户列表 4)群聊(广播) 5)点对点聊天 6)离线留言 主界面 首先,在项目根目录下初始化mod,然后按照如下结构设计目录: 海量用户通信系统/ ├── go.mod ├── client/ │ ├──…...
Windows安全加固详解
一、补丁管理 使用适当的命令或工具,检查系统中是否有未安装的更新补丁。 Systeminfo 尝试手动安装一个系统更新补丁。 • 下载适当的补丁文件。 • 打开命令提示符或PowerShell,并运行 wusa.exe <patch_file_name>.msu。 二、账号管…...
JavaScript函数基础(通俗易懂篇)
10.函数 10.1 函数的基础知识 为什么会有函数? 在写代码的时候,有一些常用的代码需要书写很多次,如果直接复制粘贴的话,会造成大量的代码冗余; 函数可以封装一段重复的javascript代码,它只需要声明一次&a…...
云RDS MySQL迁移至本地MySQL
本地准备工作 1.安装:percona-xtrabackup 上传percona-xtrabackup-2.3.9-Linux-x86_64.tar.gz包到/usr/local tar -zxvf percona-xtrabackup-2.3.9-Linux-x86_64.tar.gz mv percona-xtrabackup-2.3.9-Linux-x86_64 percona-xtrabackup 2.创建数据目录 cd /data/ mkdir rds-mys…...
【C++ 11】nullptr 空指针
文章目录 【 0. 问题背景 】0.1 野指针和悬空指针0.2 传统空指针 NULL0.3 传统空指针的局限性 【 1. 基本用法 】【 2. nullptr 的应用 】2.1 nullptr 解决 NULL 的遗留BUG2.2 简单实例 【 0. 问题背景 】 0.1 野指针和悬空指针 总结 野指针悬空指针产生原因指针变量未被初始…...
Flutter + Three.js (WebView)实现桌面端3d模型展示和交互
文章目录 flutter(桌面端)瓶颈一、Flutterthree.js二、Flutterthree.js 实现思路1.在Flutter 中使用webview 进行嵌套2.开启上面嵌套的页面地址2.在含有three.js 的html 中引入模型3.两个页面之间进行通信,如图: 总结 flutter(桌面端)瓶颈 Flutter 本身…...
学习日志35
拆卸线问题(Disassembly Line Balancing Problem, DLBP)是生产工程和运筹学中的一个特殊问题,它涉及到将废弃产品有效地拆解成可回收利用的部件和材料。随着环保意识的增强和资源回收技术的发展,DLBP逐渐成为研究的热点。这类问题…...
http cache-control
Cache-Control 是 HTTP 协议中用于控制缓存行为的重要头部字段。它定义了客户端和服务器端如何缓存资源,以及缓存的有效期。以下是关于 Cache-Control 的详细解释: 请求指令 max-age 指示客户端接受的响应最大年龄。如果缓存的响应超过这个年龄&#x…...
kubernetes 中的微服务
微服务:用控制器来完成集群的工作负载,那么应用如何暴漏出去?需要通过微服务暴漏出去后才能被访问 - Service是一组提供相同服务的Pod对外开放的接口。 - 借助Service,应用可以实现服务发现和负载均衡。 - service默认只支持…...
电脑无法无线投屏的解决办法
在前司的时候经常遇到电脑无法使用无线投屏器的情况,今天就来聊聊如何解决。 1.不会连接。这种情况,经常发生在WIN10升级WIN11之后,一般是两种办法,一种是同时按键盘上的WINDOWS和K键,右下角就会出来连接的图标&#…...
【多重循环在Java中的应用】
多重循环在Java中的应用 介绍 多重循环是将一个循环嵌套在另一个循环体内的编程结构。Java中的 for、while 和 do...while 循环均可作为外层循环和内层循环。建议使用两层嵌套,最多不超过三层,以保持代码的可读性。 在多重循环中,外层循环执…...
JVM(Java Virtual Machine) 详解
1. JVM 内存区域划分 一个 Java 写的程序,跑起来就得到了一个 Java 进程(资源分配的基本单位) JVM 上面运行的字节码指令 1) 程序计数器(比较小的空间),保存了下一条要执行的指令的地址 这个不是 CPU 的…...
基于Dify的智能问答系统:从意图识别到规范化回复的全流程设计
1. 从零开始理解Dify智能问答系统 第一次接触Dify时,我完全被它的可视化编排能力惊艳到了。这个平台就像搭积木一样,让不懂代码的产品经理也能设计出复杂的AI应用。举个实际例子,去年我们团队要做一个游泳健身领域的问答助手,传统…...
AI算力网络抉择:深度剖析RoCE与InfiniBand的实战选型指南
1. 为什么AI算力网络需要RDMA技术? 当你看到大模型训练任务卡在99%进度条时,那种焦灼感我深有体会。去年我们团队在调试千卡集群时就遇到过这种情况——原本预计72小时完成的训练任务,因为网络延迟问题硬是拖了整整一周。这就是为什么现在所…...
掌握LSLib:解锁《神界原罪》与《博德之门3》MOD制作的神器
掌握LSLib:解锁《神界原罪》与《博德之门3》MOD制作的神器 【免费下载链接】lslib Tools for manipulating Divinity Original Sin and Baldurs Gate 3 files 项目地址: https://gitcode.com/gh_mirrors/ls/lslib LSLib是一个功能强大的开源工具集࿰…...
环境管理从未如此简单:Miniconda-Python3.9镜像快速入门指南
环境管理从未如此简单:Miniconda-Python3.9镜像快速入门指南 1. 为什么选择Miniconda-Python3.9镜像 Python作为当今最流行的编程语言之一,在数据科学、机器学习和Web开发等领域有着广泛应用。但Python环境管理一直是开发者面临的痛点之一,…...
intv_ai_mk11保姆级教学:输入‘你好’→追问第2点→指定表格输出,完整交互链路演示
intv_ai_mk11保姆级教学:输入你好→追问第2点→指定表格输出,完整交互链路演示 1. 快速了解intv_ai_mk11 intv_ai_mk11是一款基于Llama架构的AI对话助手,拥有7B参数规模,运行在GPU服务器上。它能帮助你完成各种任务,…...
丹青识画GPU算力优化部署教程:显存占用降低40%实操
丹青识画GPU算力优化部署教程:显存占用降低40%实操 1. 引言:当艺术邂逅算力,如何优雅地“瘦身”? 想象一下,你刚部署好一个能看懂画作、还能用书法题诗的AI应用——“丹青识画”。它融合了前沿的多模态AI与东方美学&…...
激发创意:利用快马平台ai模型辅助设计与优化cmhhc算法
激发创意:利用快马平台AI模型辅助设计与优化CMHHC算法 最近在做一个字符串压缩相关的项目,需要实现一个自定义的压缩算法CMHHC。这个算法的核心思想其实很简单:对于连续出现的相同字符,用该字符加上出现次数来表示。比如"aa…...
GAN训练过程可视化神器对比:GAN Lab和TensorFlow Playground到底怎么选?
GAN训练可视化工具深度评测:从交互设计到教学效果的全面对比 当开发者第一次接触生成对抗网络(GAN)时,往往会被其复杂的对抗训练机制所困扰。传统的静态图表和数学公式很难直观展示生成器与判别器之间微妙的博弈过程。这正是可视化…...
实战指南:基于快马平台与Touchgal,从零开发移动端手写绘图应用
今天想和大家分享一个实战项目:基于Touchgal开发移动端手写绘图应用。这个项目特别适合需要复杂手势交互的场景,比如绘图软件、地图导航等。下面我会详细介绍整个开发流程和关键实现点。 项目初始化与环境搭建 首先需要创建一个基础的HTML5项目结构。画…...
基于博途1200PLC + HMI的交通灯控制系统仿真:打造灵活交通指挥中枢
基于博途1200PLCHMI交通灯/红绿灯控制系统仿真(时间可设置) 程序: 1、任务:PLC.人机界面控制交通灯 2、系统说明: 系统设有手动模式、自动模式、黄闪模式、红绿灯时间可设置、各灯可单独手动模式、故障模拟模式、数码管显示等模式运行 交通灯…...
