Linus 文件处理(一)

news2024/12/24 21:10:24

目录

一、前言

二、低级文件访问

1、write

2、read

3、open

4、Initial Permissions

(1)umask

(2)close

(3)ioctl

(4)第一个 copy_system.c 程序

(5)第二个 copy_block.c 程序

5、Other System Calls for Managing Files

(1)lseek

(2)fstat, stat, and lstat

(3)dup and dup2 


一、前言

本文将简单介绍Linux文件和目录,以及如何操作它们(如何创建文件、打开、读、写和关闭,程序如何操作目录,如创建、扫描和删除目录等)。本文大部分内容将会介绍处理文件和目录的各种调用,涵盖了与文件相关的部分主题:(1)文件和设备;(2)系统调用;(3)库函数;(4)低级文件访问;(5)管理文件;(6)标准I/O库;(7)格式化的输入和输出;(8)文件和目录维护;(9)扫描目录;(10)错误;(11)/proc文件系统;(12)fcntl 和 mmap。这些内容本博客不会全部介绍,只是进行部分的基础介绍。

二、低级文件访问

每个正在运行的程序称为进程,它有许多与之相关联的文件描述符。当一个程序启动时,它通常已经打开了三个这样的描述符,可以使用它们访问打开的文件或设备。

0: Standard input
1: Standard output
2: Standard error

自动打开的文件描述符已经能够让我使用 write 创建一些简单的程序。

1、write

write 系统调用安排将 buf 中的第一个 nbytes 字节写入与文件描述符文件相关联的文件。

它返回实际写入的字节数。

如果文件描述符中有错误,或者如果底层设备驱动程序对块大小非常敏感,则此值可能小于  nbytes。

如果函数返回 0,则表示没有写入数据;

如果它返回 -1,则表示写调用中存在错误,并且错误将在 errno 全局变量中指定。

 #include <unistd.h>
size_t write(int fildes, const void *buf, size_t nbytes);

写一个小demo,simple_write.c:

这个程序只是将一条消息打印到标准输出。

当程序退出时,所有打开的文件描述符都会自动关闭,因此不需要显式地关闭它们。但是,处理缓冲输出时,情况就不是这样了。

$ ./simple_write
Here is some data
$

值得再次注意的一点是,write 可能写入的字节比要求的少,这并不一定是一个错误。在程序中,可以去 check errno 来检测错误,并调用 write 来写入任何剩余的数据。

2、read

read 系统调用从与文件描述符文件相关联的文件中读取最多 nbytes 字节的数据,并将它们放在数据区 buf 中。

它返回实际读取的数据字节数,可能小于请求的数据字节数。

如果 read 调用返回 0,则它没有可读的内容,它到达了文件的末尾。

同样,调用上的错误将导致它返回 -1。

这个程序 simple_read.c 将标准输入的前 128 字节复制到标准输出。如果输入少于128字节,它将复制所有输入。 

运行程序:

要有 “东西” 重定向到 ./simple_read 中。

3、open

要创建一个新的文件描述符,我们需要使用打开系统调用。

oflags 被指定为强制文件访问模式和其他可选模式的组合。open 调用必须指定下表中所示的文件访问模式之一:

当然 oflags 还包含其他 or 组合的可选形参,感兴趣的 uu 可以自行搜索了解~使用 man 2 查询手册页是个很好的查询方式

如果成功,open 返回新的文件描述符(总是一个非负整数),如果失败,则返回 -1,这时 open 还设置全局变量 errno,以指示失败的原因。

一个正在运行的程序一次可以打开的文件数量是有限的。这个限制通常由 limit .h 中的常量 OPEN_MAX 定义,它因系统而异,但 POSIX 要求它至少为 16 。这个限制本身可能受到本地系统范围的限制,因此程序可能不总是能够打开这么多文件。在 Linux 上,这个限制可能在运行时改变,因此 OPEN_MAX 不是一个常数,它通常从 256 开始。

4、Initial Permissions

(1)umask

umask 是一个系统变量,它为创建文件时使用的文件权限编码掩码。您可以通过执行 umask 命令来更改该变量,以提供一个新值。该值为三位八进制值。每个数字都是来自 1、2 或 4 的 ORing 值的结果,其含义如下表所示。分开的数字分别代表 “user”、“group” 和 “other” 权限。

 例如,要阻止 “group” 的写和执行,以及 “other” 的写,umask 将是:

每个数字的值都是 or, 所以第二个数字应该是 2 | 1,得到3。故umask结果是032。

当通过 open 或 create 调用创建文件时,mode 参数将与当前的 umask 进行比较。在模式参数中同时在 umask 中设置的任何位都将被移除。最终的结果是,用户可以设置他们的环境说“不要为别人创建任何具有写权限的文件,即使创建文件的程序请求这种权限。” 这并不阻止程序或用户随后使用 chmod 命令(或程序中的 chmod 系统调用)添加其他写权限,但它确实有助于保护用户,使他们不必检查和设置所有新文件的权限。

(2)close

使用 close 终止文件描述符、fildes 及其文件之间的关联。文件描述符可以重用。如果成功则返回0,如果出错则返回 -1。

注意,检查 close 的返回结果可能很重要。一些文件系统,特别是网络文件系统,可能在文件关闭之前不会报告写入文件的错误,因为在执行写入操作时,数据可能没有被确认为已写入。

(3)ioctl

ioctl 是一些杂七杂八的东西。它为控制设备及其描述符的行为和配置底层服务提供了一个接口。终端、文件描述符、套接字,甚至磁带驱动器都可能有为它们定义的 ioctl 调用,用的时候需要参考特定设备的手册页了解详细信息。POSIX 仅为“流”定义 ioctl。语法如下:

ioctl 在描述符字段引用的对象上执行 CMD 指示的函数。它可以有第三个可选参数,这取决于特定设备支持的函数。

例如,在 Linux 上调用 ioctl 打开键盘 led:

现在我们已经了解了 open 、 read 和 write 系统调用,以便编写低级程序 copy_system.c,逐个字符地将一个文件复制到另一个文件。

为了简单起见,我们假设输入文件存在,而输出文件不存在,并且所有的读写操作都成功。当然,在实际的程序中,我们会检查这些假设是否有效。

(4)第一个 copy_system.c 程序

1、首先,先创建一个测试输入文件,大小为1Mb,并将其命名为 file.in

2、然后编译 copy_system.c:

#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>

int main()
{
    char c;
    int in,out;

    in=open("file.in",O_RDONLY);
    out=open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
    while(read(in,&c,1)==1)
        write(out,&c,1);

    exit(0);
}

注意,#include <unistd.h> 行必须放在前面,因为它定义了有关 POSIX 遵从性的标志,这些标志可能会影响其他包含文件。

可以用上图的命令查看耗时和CPU占用情况。

(5)第二个 copy_block.c 程序

你可以通过复制更大的块来改善这个问题。看看这个修改过的程序 copy_block.c,它同样使用系统调用将文件复制为1K块:

#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>

int main()
{
    char block[1024];
    int in,out;
    int nread;

    in=open("file.in",O_RDONLY);
    out=open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
    while((nread=read(in,block,sizeof(block)))>0)
        write(out,block,nread);

    exit(0);
}

5、Other System Calls for Managing Files

还有许多其他的系统调用操作这些低级文件描述符。这些允许程序控制文件的使用方式和返回状态信息。

(1)lseek

lseek 系统调用设置文件描述符 fildes 的读/写指针。也就是说,可以使用它来设置下次读或写将发生在文件中的什么位置。可以将指针设置为文件中的绝对位置或相对于当前位置或文件末尾的位置。

offset 参数用于指定位置,下面的参数指定如何使用偏移量。

lseek 返回文件指针所指向的文件开头的偏移量(以字节为单位),失败时返回 -1。off_t 类型用于seek 操作中的偏移量,是在 sys/types.h 中定义的一个依赖于实现的整数类型。

(2)fstat, stat, and lstat

fstat 系统调用返回与打开的文件描述符相关联的文件的状态信息。信息被写入结构 buf,其地址作为参数传递。

注意,sys/types.h 是可选的,但我们建议在使用系统调用时使用它,因为它们的一些定义对标准类型使用别名,这些标准类型可能有一天会更改。

相关函数 stat 和 lstat 返回指定文件的状态信息。它们产生相同的结果,除非文件是符号链接 lstat返回关于链接本身的信息,stat 返回链接所指向的文件的信息。

结构的成员 stat 在类 unix 系统中可能有所不同,但将包括下表中的成员:

在统计结构中返回的 st_mode 标志也有一些在头文件 sys/stat.h 中定义的相关宏。这些宏包括权限和文件类型标志的名称和一些掩码,以帮助测试特定类型和权限。

权限标志与前面描述的开放系统调用相同。文件类型标志包括:

 其他模式标志包括:

 解释 st_mode 标志的掩码包括:

定义了一些宏来帮助确定文件类型。它们只是将适当的掩码模式标志与适当的设备类型标志进行比较。这些包括:

例如,要测试一个文件是否不代表目录,是否具有所有者的执行权限集,但没有其他权限,可以使用以下测试: 

(3)dup and dup2 

dup 系统调用提供了一种复制文件描述符的方法,提供了访问同一文件的两个或多个不同的描述符。它们可能用于对文件中的不同位置进行读写。dup 系统调用复制文件描述符 fildes,返回一个新的描述符。dup2 系统调用通过指定用于复制的描述符,有效地将一个文件描述符复制到另一个文件描述符。

当使用通过管道通信的多个进程时,这些调用也很有用。在以后的学习中再深入地研究一下dup系统。

以上,Linus 文件处理(一)

祝好

 

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

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

相关文章

Apache ShardingSphere(一) 基本概念介绍

文章目录一 基本介绍1.1 概述1.2 ShardingSphere JDBC1.3 ShardingSphere Proxy1.4 ShardingSphere Sidecar1.5 数据库的扩展1.5.1 向上扩展1.5.2 横向扩展1.5.2.1 读写分离1.5.2.2 垂直切分1.5.2.3 水平切分1.6 分库与分表1.6.1 水平分库1.6.2 水平分表1.6.3 垂直分库1.6.4 垂…

[iOS]使用MonkeyDev完成Hook

一、确定目标 先定个小目标&#xff0c;使用七猫举个例&#xff0c;去移除小说阅读页底部广告和章节之间的广告。 二、HOOK 1. 创建MonkeyApp项目导入砸壳包 2. 使用Reveal工具确定“底部广告”和“章末广告”的视图名称 底部广告 View Controller: Class: QMReader.YYReade…

Strassen矩阵乘法问题(Java)

Strassen矩阵乘法问题&#xff08;Java&#xff09; 文章目录Strassen矩阵乘法问题&#xff08;Java&#xff09;1、前置介绍3、代码实现4、复杂度分析5、参考资料1、前置介绍 矩阵乘法是线性代数中最常见的问题之一 &#xff0c;它在数值计算中有广泛的应用。 设A和B是2个nXn…

搭建灾情快速分析系统 | Bigemap助力防灾减灾重点工作

Bigemap国产基础软件凭借自身强大的新GIS引擎技术与完善的产品链&#xff0c;为相关部门提供了集"灾情采集-灾情监测-灾害快速评估-应急指挥"于一体的灾害防灾减灾解决方案&#xff0c;搭建了灾情快速分析系统&#xff0c;该系统成为相关部门应对灾情的重要支撑平台。…

虚拟号码认证如何开通?

近年来&#xff0c;经常会接到外卖、房产中介、信用贷款等电话&#xff0c;让顾客不胜其扰。现在电话标记功能使用越来越普遍&#xff0c;可以大概了解电话“来意”&#xff0c;同时也会让误标记、恶意标记很方便。对于开展业务或办公司或企业的人&#xff0c;更加不能让自己的…

排序算法之选择排序

今天来给大家介绍一下排序算法之选择排序 选择排序&#xff1a;&#xff08;Selection sort&#xff09;是一种简单直观的排序算法&#xff0c;也是一种不稳定的排序方法。 选择排序的原理&#xff1a; 一组无序待排数组&#xff0c;做升序排序&#xff0c;我们先假定第一个…

【生成模型】Diffusion Models:概率扩散模型

---前言一、Diffusion Model 基本介绍二、生成模型对比三、直观理解Diffusion model四、形式化解析Diffusion model五、详解 Diffusion Model&#xff08;数学推导&#xff09;1.前向过程(扩散过程)2.逆扩散过程3.逆扩散条件概率推导4.训练损失六、训练、测试伪代码1. 训练2.测…

鲲鹏devkit编译调试工具——《sudoku》作业解析

《sudoku》作业解析 本次实验以sudoku项目为例介绍鲲鹏编译调试插件的基本使用方法 本次实验的步骤主要为 获取源码安装鲲鹏编译调试插件服务器配置进行代码同步配置配置测试任务进行编译调试 接下来我们先获取本次实验所需要的源码 获取源码 sudoku项目已经上传到github使…

stata外部命令大全(包含面板门槛、系统GMM、空间计量、Pvar、中介效应等)

1、数据来源&#xff1a;自主整理 2、时间跨度&#xff1a;无 3、区域范围&#xff1a;无 4、指标说明&#xff1a; 该些外部命令包含面板门槛、系统GMM、空间计量、pvar、中介效应等涵盖全部 以下是部分命令截图&#xff1a; 空间计量&#xff1a; 系统GMM&#xff08;动…

Allure使用手册

一. 简介 Allure是一款支持多语言的测试结果可视化软件&#xff0c;支持Java、Python&#xff0c;搭配Junit、pytest等测试框架食用更香。本文主要讲解搭配Junit4。 二. 下载、安装部署 2.1 下载 百度搜索Allure2&#xff01;&#xff01;&#xff01; 敲重点&#xff1a;…

基于Qlearning强化学习的倒立摆控制系统matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 强化学习通常包括两个实体agent和environment。两个实体的交互如下&#xff0c;在environment的statestst下&#xff0c;agent采取actionatat进而得到rewardrtrt 并进入statest1st1。Q-l…

【头歌实验】五、Python循环结构

文章目录>>>第1关&#xff1a;达依尔的麦子数任务描述案例分析相关知识for循环测试说明参考答案>>>第2关&#xff1a;四级单词查询任务描述案例分析相关知识如何处理文件文件打开文件循环文件关闭遍历文件测试说明第3关&#xff1a;出租车车费计算任务描述案…

Monaco Editor教程(十八):使用api来完成某些键盘操作,格式化,查找,显示右侧菜单等。

背景 在一般的Web IDE中&#xff0c;我们需要将经常用到的一些操作放到顶部操作栏里&#xff0c;类似语雀的文档编辑。 代码编辑器&#xff0c;一般也会放一些查找&#xff0c;格式化&#xff0c;撤销&#xff0c;恢复。有些人喜欢用快捷键来进行这些操作&#xff0c;但由于mo…

Packet Tracer - 配置 OSPF 高级功能

地址分配表 设备 接口 IPv4 地址 子网掩码 默认网关 R1 G0/0 172.16.1.1 255.255.255.0 不适用 S0/0/0 172.16.3.1 255.255.255.252 不适用 S0/0/1 192.168.10.5 255.255.255.252 不适用 R2 G0/0 172.16.2.1 255.255.255.0 不适用 S0/0/0 172.16.3.2 …

论文笔记: 全波形反演的无监督学习: 将 CNN 与偏微分方程做成一个环

摘要: 分享对论文的理解, 原文见 Peng Jin, Xitong Zhang, Yinpeng Chen, Sharon Xiaolei Huang, Zicheng Liu, Youzuo Lin, Unsupervised learning of full-waveform inversion: connecting CNN and partial differential equation in a loop. 论文发表于计算机方面的顶会 ICL…

(续)SSM整合之SSM整合笔记(Spring整合MyBatis)(P179-188)

一 准备工作 1 新建模块ssm com.atguigu.ssm 2 导入依赖 <packaging>war</packaging><properties><spring.version>5.3.1</spring.version> </properties><dependencies><dependency><groupId>org.springframewo…

Linux:进程(二)

文章目录前言一、环境变量1.概念2.常见环境变量3.一个疑问4.通过系统调用获取或设置环境变量二、地址空间1.引入2.分页&进程地址空间1.页表2.写时拷贝3.为什么要有地址空间总结前言 今天我们继续学习进程相关知识。 一、环境变量 1.概念 环境变量(environment variables)…

从理解路由到实现一套Router(路由)

平时在Vue项目中经常用到路由&#xff0c;但是也仅仅处于会用的层面&#xff0c;很多基础知识并不是真正的理解。于是就趁着十一”小长假“查阅了很多资料&#xff0c;总结下路由相关的知识&#xff0c;查缺不漏&#xff0c;加深自己对路由的理解。 路由 在 Web 开发过程中&a…

Redis中最简单的存储类型:String

String类型&#xff0c;也就是字符串类型&#xff0c;是Redis中最简单的存储类型。 其value是字符串&#xff0c;不过根据字符串的格式不同&#xff0c;又可以分为3类&#xff1a; string&#xff1a;普通字符串 int&#xff1a;整数类型&#xff0c;可以做自增、自减操作 f…

CentOS虚拟机装完了,不能粘贴window命令行?不能上网?

文章目录前言关于CentOS安装版本如何实现粘贴命令行CentOS命令行模式下如何联网&#xff1f;结尾前言 最近想系统学习Linux环境下系统运维&#xff0c;所以安装了CentOS 7虚拟机&#xff0c;但是个人笔记本上和工作电脑上无意中下载了不同镜像进行安装&#xff0c;有一台机器无…