嵌入式Linux系统编程 — 3.7 文件目录与处理

news2024/11/19 10:42:35

目录

1 文件目录

1.1 文件目录简介

1.2 目录存储形式

2 创建和删除目录

2.1 mkdir创建目录

2.2 rmdir删除空目录

3 opendir打开、 readdir读取以及closedir关闭目录

3.1 打开文件 opendir

3.2 读取目录 readdir

3.3 重置目录起点rewinddir

3.4 关闭目录 closedir

3.4 示例程序 

4 进程的当前工作目录 

4.1 获取进程的当前工作目录getcwd

4.2 改变当前工作目录chdir()和 fchdir()

5 删除文件

5.1 unlink 函数删除文件

5.2 remove 函数删除文件

5 文件重命名renme


1 文件目录

1.1 文件目录简介

在Linux系统中,文件目录(也常称为文件夹)是一种特殊的文件,它用于组织和管理文件系统中的文件和子目录。目录本身也被视为文件,但是它们具有一些特殊的属性和操作方式,不同于普通文件。

在 Linux 系统下,会有一些专门的系统调用或 C 库函数用于对文件夹进行操作,譬如:打开、创建文件夹、删除文件夹、读取文件夹以及遍历文件夹中的文件等。

1.2 目录存储形式

目录在文件系统中的存储方式与常规文件类似,常规文件包括了 inode 节点以及文件内容数据存储块(block);但对于目录来说, 其存储形式则是由 inode 节点和目录块所构成,目录块当中记录了有哪些文件组织在这个目录下,记录它们的文件名以及对应的 inode 编号。其存储形式如下图所示:

目录块当中有多个目录项(或叫目录条目) ,每一个目录项(或目录条目) 都会对应到该目录下的某一个文件,目录项当中记录了该文件的文件名以及它的 inode 节点编号,所以通过目录的目录块便可以遍历找到该目录下的所有文件以及所对应的 inode 节点。

2 创建和删除目录

2.1 mkdir创建目录

mkdir 函数是C语言标准库中的一个函数,用于在文件系统中创建一个新的目录。这个函数的原型如下:

#include <sys/stat.h> 

int mkdir(const char *pathname, mode_t mode);
  • pathname指向一个以null结尾的字符串,指定要创建的目录的路径。
  • mode用于设置新目录的权限。这个值通常使用S_IRWXU(所有者读、写、执行权限) | S_IRWXG(组读、写、执行权限) | S_IRWXO(其他用户读、写、执行权限)的组合来定义。

下面是一个使用命令行参数来创建目录的示例程序:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>

int main(int argc, char *argv[]) 
{
    // 检查是否提供了目录名作为命令行参数
    if (argc != 2) {
        fprintf(stderr, "Usage: %s directory_name\n", argv[0]);
        return EXIT_FAILURE;
    }

    const char *dir = argv[1]; // 命令行参数作为目录名
    mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; // 所有者、组和其他用户都有读、写、执行权限

    if (mkdir(dir, mode) == -1) {
        if (errno == EEXIST) {
            printf("Directory '%s' already exists.\n", dir);
        } else {
            perror("mkdir failed"); // perror函数会打印错误信息
        }
        return errno;
    }

    printf("Directory '%s' created successfully\n", dir);
    return 0;
}

程序在运行时提供一个参数,即目录名。如果用户提供了正确的参数数量,程序将尝试创建一个具有指定权限的目录。如果目录创建成功,程序将打印一条成功消息。如果目录已经存在,程序将打印一条相应的消息。如果发生其他错误,perror 函数将打印错误信息。程序运行结果如下:

2.2 rmdir删除空目录

rmdir 函数是C语言标准库中用于删除空目录的函数。如果目录不为空,rmdir 函数将失败。以下是 rmdir 函数的原型:

#include <unistd.h>

int rmdir(const char *pathname);
  • pathname:指向一个以null结尾的字符串,指定要删除的目录的路径。

 下面是一个使用 main 函数和命令行参数来删除目录的示例程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[]) 
{
    // 检查是否提供了目录名作为命令行参数
    if (argc != 2) {
        fprintf(stderr, "Usage: %s directory_name\n", argv[0]);
        return EXIT_FAILURE;
    }

    const char *dir = argv[1]; // 命令行参数作为目录名

    if (rmdir(dir) == -1) {
        if (errno == ENOTEMPTY) {
            printf("Directory '%s' is not empty.\n", dir);
        } else {
            perror("rmdir failed"); // perror函数会打印错误信息
        }
        return errno;
    }

    printf("Directory '%s' removed successfully\n", dir);
    return 0;
}

程序在运行时提供一个参数,即要删除的目录名。如果提供了正确的参数数量,程序将尝试删除该目录。如果目录删除成功,程序将打印一条成功消息。如果目录不为空,程序将打印一条相应的消息。

3 opendir打开、 readdir读取以及closedir关闭目录

3.1 打开文件 opendir

opendir()函数用于打开一个目录,并返回指向该目录的句柄,供后续操作使用。 Opendir 是一个 C 库函数, opendir()函数原型如下所示:

#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);
  • name: 指定需要打开的目录路径名,可以是绝对路径,也可以是相对路径。
  • 返回值: 成功将返回指向该目录的句柄,一个 DIR 指针(其实质是一个结构体指针),其作用类似于open函数返回的文件描述符fd,后续对该目录的操作需要使用该DIR指针变量;若调用失败,则返回NULL。

3.2 读取目录 readdir

readdir()用于读取目录,获取目录下所有文件的名称以及对应 inode 号。readdir()是一个 C 库函数(事实上 Linux 系统还提供了一个 readdir 系统调用),其函数原型如下所示:

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

dirp: 目录句柄 DIR 指针。
返回值: 返回一个指向 struct dirent 结构体的指针, 该结构体表示 dirp 指向的目录流中的下一个目录条目。在到达目录流的末尾或发生错误时,它返回 NULL。

每调用一次 readdir(),就会从 drip 所指向的目录流中读取下一条目录项(目录条目),并返回 struct dirent结构体指针(struct dirent 结构体记录了文件的 inode 编号和文件名等信息)。

当使用 opendir()打开目录时,目录流将指向了目录列表的头部(0) ,使用 readdir()读取一条目录条目之后,目录流将会向后移动、指向下一个目录条目。这其实跟 open()类似, 当使用 open()打开文件的时候,文件位置偏移量默认指向了文件头部,当使用 read()或 write()进行读写时,文件偏移量会自动向后移动。

3.3 重置目录起点rewinddir

rewinddir()是 C 库函数,可将目录流重置为目录起点, 以便对 readdir()的下一次调用将从目录列表中的第一个文件开始。 rewinddir 函数原型如下所示:

#include <sys/types.h>
#include <dirent.h>

void rewinddir(DIR *dirp);
  • dirp: 目录句柄

3.4 关闭目录 closedir

closedir()函数用于关闭处于打开状态的目录,同时释放它所使用的资源,其函数原型如下所示:

#include <sys/types.h>
#include <dirent.h>

int closedir(DIR *dirp);

3.4 示例程序 

下面的示例程序接收命令行参数作为目录名,然后列出该目录下的所有文件和目录项:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>

int main(int argc, char *argv[]) 
{
    // 检查是否提供了目录名作为命令行参数
    if (argc != 2) {
        fprintf(stderr, "Usage: %s directory_name\n", argv[0]);
        return EXIT_FAILURE;
    }

    const char *dir_name = argv[1]; // 命令行参数作为目录名
    DIR *dir_ptr = NULL;
    struct dirent *entry;

    // 打开目录以供读取
    dir_ptr = opendir(dir_name);
    if (dir_ptr == NULL) {
        perror("opendir failed"); // perror函数会打印错误信息
        return errno;
    }

    // 读取目录中的所有条目
    while ((entry = readdir(dir_ptr)) != NULL) {
        printf("%s\n", entry->d_name); // 打印文件或目录名
    }

    // 关闭目录流
    if (closedir(dir_ptr) == -1) {
        perror("closedir failed");
        return errno;
    }

    return 0;
}

在这个示例中,程序首先检查命令行参数的数量是否正确。如果正确,它将尝试打开指定的目录。如果目录成功打开,程序将使用 readdir 函数遍历目录中的所有条目,并打印每个条目的名称。最后,使用 closedir 函数关闭目录流。程序运行结果如下:

4 进程的当前工作目录 

4.1 获取进程的当前工作目录getcwd

getcwd 函数是 POSIX 标准定义的用于获取当前工作目录的完整路径的函数。以下是 getcwd 函数的原型:

#include <unistd.h> 

char *getcwd(char *buf, size_t size);
  • buf:指向一个字符数组的指针,用于存储当前工作目录的路径。如果为 NULLgetcwd 将分配一个足够大的缓冲区。
  • size:缓冲区的大小。

下面是使用 getcwd 函数的示例程序,该程序将打印当前工作目录的路径:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(void) {
    char *buffer;
    size_t bufferSize = 1024;

    // 尝试获取当前工作目录
    buffer = getcwd(NULL, bufferSize); // 使用 NULL 让 getcwd 分配缓冲区
    if (buffer == NULL) {
        perror("getcwd failed"); // perror 函数会打印错误信息
        return errno;
    }

    // 打印当前工作目录
    printf("Current working directory: %s\n", buffer);

    // 释放 getcwd 分配的缓冲区
    free(buffer);

    return 0;
}

getcwd 被用来获取当前工作目录的路径,并将结果存储在 buffer 中。如果 getcwd 成功,程序将打印当前工作目录的路径。如果失败,perror 函数将打印错误信息。最后,如果 getcwd 分配了缓冲区,程序将使用 free 函数释放它。运行结果如下:

4.2 改变当前工作目录chdir()和 fchdir()

chdir()fchdir() 是两个用于更改当前工作目录的函数,两个函数的原型如下:

#include <unistd.h> 

int chdir(const char *path);
  • path:指向以null结尾的字符串的指针,指定要切换到的目录的路径。
#include <unistd.h> 

int fchdir(int fd);
  • fd:文件描述符,指向一个目录的文件描述符。

5 删除文件

5.1 unlink 函数删除文件

unlink 函数用于删除文件的函数,以下是 unlink 函数的原型:

#include <unistd.h> 

int unlink(const char *pathname);
  • pathname:指向以null结尾的字符串的指针,指定要删除的文件的路径。

下面是一个使用 unlink 函数删除文件的示例程序,该程序接收命令行参数作为要删除的文件名:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[]) {
    // 检查是否提供了文件名作为命令行参数
    if (argc != 2) {
        fprintf(stderr, "Usage: %s filename\n", argv[0]);
        return EXIT_FAILURE;
    }

    const char *filename = argv[1]; // 命令行参数作为文件名

    // 尝试删除文件
    if (unlink(filename) == -1) {
        perror("unlink failed"); // perror 函数会打印错误信息
        return errno;
    }

    printf("File '%s' has been successfully deleted\n", filename);
    return 0;
}

程序首先检查命令行参数的数量是否正确。如果正确,它将尝试删除指定的文件。如果文件删除成功,程序将打印一条成功消息。如果删除失败,perror 函数将打印错误信息。运行结果如下,从测试结果可看到,只能删除文件,不能删除文件夹

5.2 remove 函数删除文件

remove 函数是C标准库中的一个函数,它可以删除文件或空目录。与unlink不同,remove可以删除空目录,但不能删除非空目录。以下是remove函数的原型:

#include <stdio.h> 

int remove(const char *filename);
  • filename:指向以null结尾的字符串的指针,指定要删除的文件或目录的路径。

示例程序将5.1中的unlink变为remove ​​​​​​​,运行结果如下,从运行结果可以看到,remove可以删除目录。

5 文件重命名renme

rename 函数用于重命名文件或目录。以下是 rename 函数的原型:

#include <stdio.h> 

int rename(const char *oldpath, const char *newpath);
  • oldpath:指向以null结尾的字符串的指针,指定要重命名的文件或目录的当前名称。
  • newpath:指向以null结尾的字符串的指针,指定新的名称。

下面是 rename 函数重命名文件的示例程序,程序接收两个命令行参数:oldpathnewpath: 

程序首先检查命令行参数的数量是否正确。如果正确,它将尝试将文件或目录从 oldpath 重命名为 newpath。如果重命名成功,程序将打印一条成功消息。如果重命名失败,perror 函数将打印错误信息。

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

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

相关文章

《数字图像处理》实验报告五

一、实验任务与要求 实现一个自适应局部降噪滤波器&#xff1b;在一幅测试版图像中加入运动模糊和高斯噪声&#xff0c;产生一幅退化图像&#xff0c;采用 deconvwnr 函数实现逆滤波及维纳滤波。 二、实验报告 &#xff08;一&#xff09;实现一个自适应局部降噪滤波器 1、自…

入门JavaWeb之 JSP 语法、指令、内置对象和 JSTL 标签

导入 jar 包 搜索 jstl-api、standard pom.xml 导入 jar 包 <!-- Servlet 依赖 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provid…

VMamba: Visual State Space Model论文笔记

文章目录 VMamba: Visual State Space Model摘要引言相关工作Preliminaries方法网络结构2D-Selective-Scan for Vision Data(SS2D) VMamba: Visual State Space Model 论文地址: https://arxiv.org/abs/2401.10166 代码地址: https://github.com/MzeroMiko/VMamba 摘要 卷积神…

使用matlab的大坑,复数向量转置!!!!!变量区“转置变量“功能(共轭转置)、矩阵转置(默认也是共轭转置)、点转置

近期用verilog去做FFT相关的项目&#xff0c;需要用到matlab进行仿真然后和verilog出来的结果来做对比&#xff0c;然后计算误差。近期使用matlab犯了一个错误&#xff0c;极大的拖慢了项目进展&#xff0c;给我人都整emo了&#xff0c;因为怎么做仿真结果都不对&#xff0c;还…

matlab量子纠缠态以及量子门操作下的量子态

前言 今天我们来聊聊题外话&#xff0c;量子纠缠&#xff0c;在目前物理分支中&#xff0c;要说最深&#xff0c;最能改变人类对宇宙影响的莫过于量子力学了&#xff0c;假如我们可以人为的对两个粒子施加纠缠态&#xff0c;那么我们将可以足不出户的完成对外界的操控 简介 …

计算机网络:408考研|湖科大教书匠|原理参考模型II|学习笔记

系列目录 计算机网络总纲领 计算机网络特殊考点 计算机网络原理参考模型I 计算机网络原理参考模型II 目录 系列目录更新日志前言应用层(Application Layer)一、应用层概述二、客户/服务器方式和对等方式三、动态主机配置协议(DHCP, Dynamic Host Configuration Protocol)四、域…

音频概念_STFT_窗口函数

短时傅里叶变换 (Short-Time Fourier Transform, STFT) 是一种时频谱转换算法&#xff0c;它通过在时间上移动窗口函数并计算窗口内信号的频谱来获得信号在时间和频率上的信息。填充信号可以确保每个窗口都有足够的数据进行频谱计算&#xff0c;特别是在窗口函数的边缘。 窗口…

读AI新生:破解人机共存密码笔记13有益机器

1. 标准模型 1.1. 我们能控制一个从外太空来的超级智能实体的概率几乎为零 1.2. 随着根据标准模型设计的机器变得更加智能&#xff0c;以及它们的行动范围遍及全球&#xff0c;关闭机器这种方法越来越不可行 1.2.1. 机器将会追求它们自己的目标&#xff0c;无论目标错得多么…

通讯:单片机串口和电脑通讯

目录 1.串口输出数据到电脑 硬件部分 串口输出数据到电脑的软件软件部分&#xff1a; 相关问题&#xff1a; 2.单片机串口--485--485转USB--电脑 串口&#xff0c;芯片&#xff0c;转换器&#xff0c;设备之间的通讯的接线&#xff0c;都是要TX--RX, RX--TX 交叉连接。 单…

机器学习Python代码实战(二)分类算法:k-最近邻

一.k-最近邻算法步骤 1.选择适当的k值。它表示在预测新的数据点时要考虑的邻居数量。 2.计算距离。计算未知点与其他所有点之间的距离。常用的距离计算方法主要有欧氏距离&#xff0c;曼哈顿距离等。 3.选择邻居。在训练集中选择与要预测的数据点距离最近的k个邻居。 4.预测…

如何快速把一篇文章或企业介绍变为视频?

随着科技和数字化的不断发展&#xff0c;企业的营销手段也在不断变革。尤其对于产品宣传来说&#xff0c;用生动的视觉语言直观地展示产品特点和优势&#xff0c;能够彰显企业实力&#xff0c;让社会不同层面的人士对企业产生正面、良好的印象&#xff0c;从而建立对该企业的好…

Antivirus Zap Pro :苹果 mac 电脑全面的系统安全解决方案

Antivirus Zap Pro 是一个全面的系统安全解决方案&#xff0c;它可以扫描和删除 Mac 中的恶意软件和其他恶意软件&#xff0c;还可以检测 Mac 上已经存在的威胁或可疑文件&#xff0c;并保护您的 Mac 免遭日后的威胁&#xff0c;满足用户不同的 Mac 电脑杀毒需求&#xff0c;有…

【01BFS】2290. 到达角落需要移除障碍物的最小数目

本文涉及知识点 01BFS CBFS算法 图论知识汇总 LeetCode2290. 到达角落需要移除障碍物的最小数目 给你一个下标从 0 开始的二维整数数组 grid &#xff0c;数组大小为 m x n 。每个单元格都是两个值之一&#xff1a; 0 表示一个 空 单元格&#xff0c; 1 表示一个可以移除的…

聚观早报 | 小鹏MONA M03曝光;iPhone 16系列电池改进

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 6月25日消息 小鹏MONA M03曝光 iPhone 16系列电池改进 一加Ace 3 Pro三款配色 字节跳动与博通合作开发AI芯片 蚂…

GPT-5

欢迎来到 Papicatch的博客 文章目录 &#x1f349;技术突破预测 &#x1f348;算法进步 &#x1f348;理解力提升 &#x1f348;行业推动力 &#x1f349;人机协作的未来 &#x1f348;辅助决策 &#x1f348;增强创造力 &#x1f348;复杂任务中的角色 &#x1f348;人…

非极大值抑制算法(Non-Maximum Suppression,NMS)

https://tcnull.github.io/nms/ https://blog.csdn.net/weicao1990/article/details/103857298 目标检测中检测出了许多的候选框&#xff0c;候选框之间是有重叠的&#xff0c;NMS作用重叠的候选框只保留一个 算法&#xff1a; 将所有候选框放入到集和B从B中选出分数S最大的b…

Hadoop3:Yarn框架的三种调度算法

一、概述 目前&#xff0c;Hadoop作业调度器主要有三种&#xff1a;FIFO、容量&#xff08;Capacity Scheduler&#xff09;和公平&#xff08;Fair Scheduler&#xff09;。Apache Hadoop3.1.3默认的资源调度器是Capacity Scheduler。 CDH框架默认调度器是Fair Scheduler。 …

Http客户端-Feign 学习笔记

作者介绍&#xff1a;计算机专业研究生&#xff0c;现企业打工人&#xff0c;从事Java全栈开发 主要内容&#xff1a;技术学习笔记、Java实战项目、项目问题解决记录、AI、简历模板、简历指导、技术交流、论文交流&#xff08;SCI论文两篇&#xff09; 上点关注下点赞 生活越过…

EVPN-VXLAN:如何在数据中心使用

移动设备的迅速普及、社交媒体和协作工具的使用不断增加&#xff0c;使得网络中的端点数量日益增多。这种端点的快速增长促使对更有效的分段策略的需求&#xff0c;以区分不同用户、设备和流量类型。EVPN-VXLAN通过在物理第3层底层网络建立第2层覆盖虚拟网络的隧道&#xff0c;…

VMware虚拟机安装CentOS7.9 Oracle 11.2.0.4 RAC+单节点RAC ADG

目录 一、参考资料 二、RAC环境配置清单 1.主机环境 2.共享存储 3.IP地址 4.虚拟机 三、系统参数配置 1. 配置网卡 1.1 配置NAT网卡 1.2 配置HostOnly网卡 2. 修改主机名 3. 配置/etc/hosts 4. 关闭防火墙 5. 关闭Selinux 6. 配置内核参数 7. 配置grid、oracle…