C/C++遍历指定文件夹下所有文件/文件夹,并输出硬链接数大于等于2的inode节点

该篇博客介绍了如何使用C/C++编程,在WSL Ubuntu环境下,通过scandir函数遍历指定目录及其子目录,查找硬链接数为2或以上的文件。代码中使用了unordered_map存储inode号及其对应的文件名集合,并通过stat函数获取文件状态信息。通过编译和运行程序,成功展示了找到的inode号和它们的链接文件名。
摘要由CSDN通过智能技术生成

编程语言:C/C++

编程环境:WSL:Ubuntu-20.04

要求:对于给定文件名filePath,以其为根节点遍历其下包含所有的文件/文件夹,找出硬连接数为2或以上的inode节点,输出其链接文件名。

思路:

  • 通过scandir函数递归遍历filePath下的所有文件/文件夹。
  • 使用hash表(unodered_map)记录硬链接数大于等于2的节点及其关联文件集合。形式为:<Key:inode号,Value:文件名集合>
  • 对于每个遍历到的文件/文件夹,获取其绝对路径,利用stat函数读取其文件状态信息,检测其硬链接数,如果大于等于2,向对应inode号的哈希表项值添加文件名。

代码:

#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
#include <unordered_map>
#define DIRECTORY_TYPE 4
#define REGULAR_TYPE 8
using namespace std;
unordered_map<unsigned long, vector<string>> mp;//记录硬链接数大于等于2的inode信息的hash表
void Scanner(const char *filePath)
{
    //通过dirent表和scandir函数获取该目录下的文件/文件夹
    struct dirent **name_list;
    int n = scandir(filePath, &name_list, 0, alphasort);
    if (n < 0)
        printf("scandir return %d \n", n);
    else
    {
        //递归遍历用的字符串
        char tmpFileName[256] = {0};
        int index = 0;
        while (index < n)
        {
            //对于每一个遍历到的文件/文件夹,获取其文件状态信息
            struct stat b;
            //合成文件/文件夹的绝对路径
            memset(tmpFileName, '\0', sizeof(tmpFileName));
            strcpy(tmpFileName, filePath);
            tmpFileName[strlen(filePath)] = '/';
            strcat(tmpFileName, name_list[index]->d_name);

            //获取文件状态
            stat(tmpFileName, &b);
            if (b.st_nlink >= 2)
            {
                //如果硬链接数大于等于2,向对于哈希表项中添加文件名
                mp[b.st_ino].push_back(string(tmpFileName));
            }
            if (name_list[index]->d_type == DIRECTORY_TYPE && strcmp(name_list[index]->d_name, ".") != 0 && strcmp(name_list[index]->d_name, "..") != 0)
            {
                //如果文件类型是目录类型(且不是"."和".."),则递归调用Scanner扫描文件夹
                Scanner(tmpFileName);
            }
            //name_list是分配在栈中的,使用完要及时回收
            free(name_list[index++]);
        }
        //回收name_list
        free(name_list);
    }
    return;
}
int main()
{
    //扫描,记录相关信息
    Scanner("/mnt/d/VS code projects/leetcode");
    //遍历map,输出目标inode号和链接文件
    for (unordered_map<unsigned long, vector<string>>::iterator it = mp.begin(); it != mp.end(); it++)
    {
        cout << "INode:" << it->first << " "
             << "Linked File:" << endl;
        for (int i = 0; i < it->second.size(); i++)
        {
            cout << it->second[i] << "\t";
        }
        cout << endl;
    }
}

测试

首先在当前目录/mnt/d/VS code projects/leetcode(自己指定的)下新建一个文件夹1.txt,随便编辑其内容:

This is a test file.

然后在终端输入命令:

ln 1.txt 2.txt

这个命令是新建一个文件2.txt,并将其硬链接到1.txt上。

输入命令:

stat 1.txt

查看文件状态:

  File: 1.txt
  Size: 20              Blocks: 8          IO Block: 4096   regular file
Device: 32h/50d Inode: 4503599627393775  Links: 2
Access: (0777/-rwxrwxrwx)  Uid: ( 1000/     yan)   Gid: ( 1000/     yan)
Access: 2022-05-31 22:31:49.885767600 +0800
Modify: 2022-05-31 22:31:49.869438500 +0800
Change: 2022-05-31 22:31:49.869438500 +0800
 Birth: -

可以看到此时硬连接数为2。

编译运行上面的程序,控制台输出如下:

INode:4503599627393775 Linked File:
/mnt/d/VS code projects/leetcode/1.txt  /mnt/d/VS code projects/leetcode/2.txt

可以看到成功给出了满足要求的inode号,和硬链接在它上面的所有文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值