初识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 的…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
Redis上篇--知识点总结
Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...
使用ch340继电器完成随机断电测试
前言 如图所示是市面上常见的OTA压测继电器,通过ch340串口模块完成对继电器的分路控制,这里我编写了一个脚本方便对4路继电器的控制,可以设置开启时间,关闭时间,复位等功能 软件界面 在设备管理器查看串口号后&…...
