Linux下的C程序,遍历文件夹并统计其中各个类型文件所占百分比

递归遍历一个目录下的所有文件和文件夹,统计各个类型文件所占的百分比

程序代码a.cpp(编译命令:g++ a.cpp -o a)

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>

struct FileStat
{
    char m_Name[100]; //文件类型名
    int m_Count;      //文件个数统计(在main函数中计算)
    float m_Percent;  //在所有文件中占的百分比(在main函数中计算)
    FileStat(const char* name)
    {
        strcpy(this -> m_Name, name);
        this -> m_Count = 0;
        this -> m_Percent = 0;
    }
};

struct FileStat* fs[8] = 
{
    new FileStat("普通文件(REGULAR)              "),
    new FileStat("目录文件(DIRECTORY)            "),
    new FileStat("字符特殊文件(CHARACTER_SPECIAL)"),
    new FileStat("块特殊文件(BLOCK_SPECIAL)      "),
    new FileStat("管道或FIFO(FIFO)               "),
    new FileStat("符号链接(SYMBOLIC_LINK)        "),
    new FileStat("套接字(SOCKET)                 "),
    new FileStat("其他未知类型(UNKNOWN)          ")
};

struct stat buf;

//遍历文件夹
void CheckDir(char* dir, int depth)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if ((dp = opendir(dir)) == NULL)
    {
        fprintf(stderr, "Cannot Open Directory: %s\n");
        return;
    }

    chdir(dir);
    while ((entry = readdir(dp)) != NULL)
    {
        lstat(entry -> d_name, &statbuf);

        //遍历到文件夹
        if (S_ISDIR(statbuf.st_mode))
        {
            if(strcmp(".", entry -> d_name) == 0 ||
                strcmp("..", entry -> d_name) == 0)
            {
                continue;
            }

            //printf("%d|%*sDir:%s/\n", depth, depth, " ", entry -> d_name);
            fs[1] -> m_Count++;

            CheckDir(entry -> d_name, depth + 4);
        }
        else //遍历到文件
        {
            //printf("%d|%*sFile:%s | ", depth, depth, " ", entry -> d_name);
        
            if (lstat(entry -> d_name, &buf) < 0)
            {
                printf("LSTAT ERROR");
                continue;
            }

            if (S_ISREG(buf.st_mode))
            {
                //printf("普通文件 REGULAR\n");
                fs[0] -> m_Count++;
            }
            else if (S_ISCHR(buf.st_mode))
            {
                //printf("字符特殊文件 CHARACTER SPECIAL\n");
                fs[2] -> m_Count++;
            }
            else if (S_ISBLK(buf.st_mode))
            {
                //printf("块特殊文件 BLOCK SPECIAL\n");
                fs[3] -> m_Count++;
            }
            else if (S_ISFIFO(buf.st_mode))
            {
                //printf("管道或FIFO FIFO\n");
                fs[4] -> m_Count++;
            }
            else if (S_ISLNK(buf.st_mode))
            {
                //printf("符号连接 SYMBOLIC LINK\n");
                fs[5] -> m_Count++;
            }
            else if (S_ISSOCK(buf.st_mode))
            {
                //printf("套接字 SOCKET\n");
                fs[6] -> m_Count++;
            }
            else
            {
                //printf("未知类型 UNKNOWN MODE\n");
                fs[7] -> m_Count++;
            }
        }
    }

    chdir("..");
    closedir(dp);
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Input Error: Argv[1] must be a file name!\n");
        exit(1);
    }
    
    printf("Check Folder: %s\n", argv[1]);
    CheckDir(argv[1], 0);

    //计算m_Count和m_Percent
    int i, total;
    for(i = 0; i < 8; i++)
    {
        total += fs[i] -> m_Count;
    }
    for(i = 0; i < 8; i++)
    {
        fs[i] -> m_Percent = 1.0 * fs[i] -> m_Count / total;
    }

    //输出计算结果
    printf("                    STAT                    \n");
    printf("============================================\n");
    for(i = 0; i < 8; i++)
    {
        printf("%s | %7.3f%%\n", fs[i] -> m_Name, 100.0 * fs[i] -> m_Count / total);
    }
    printf("Done.\n");

    return 0;
}

运行结果

END

时间: 2024-08-04 18:04:01

Linux下的C程序,遍历文件夹并统计其中各个类型文件所占百分比的相关文章

File类——renameTo()将文件夹内的所有指定类型文件 移动到另一个文件夹内

* 由于   张孝祥-7K月薪面试题破解之一_交通灯管理系统视频教程 文件夹下 的视频文件都存放在每个子文件夹中 * 需求:将所有视频文件全部移动到  张孝祥-7K月薪面试题破解之一_交通灯管理系统视频教程文件夹下  原来存放视频的子文件夹删除 public class moveFiles { public static void main(String[] args) { // TODO Auto-generated method stub File f = new File("D:\\Bai

Linux下Qt应用程序的发布(使用LDD命令查看所有依赖的库文件)

最近一直在学习Qt,用Qt写了一个程序,但是不知道怎么发布,网上说的都是在windows下怎么发布Qt应用程序,但是,在windows下Qt应用程序依赖的库文件与linux下的名字不同.于是,我就想到Linux下有没有这么一个命令,能够找到一个可执行文件运行时所依赖的库文件,百度一下,还真的有ldd命令. ldd的作用是打印可执行文件依赖的共享库文件,它是glibc的一部分: [email protected]:~# ldd --helpUsage: ldd [OPTION]... FILE..

【转帖】Linux文件夹对比并提取的差分文件技巧-rsync的妙用

Linux文件夹对比并提取的差分文件技巧-rsync的妙用 [日期:2016-02-13] 来源:oschina.net  作者:mengshuai [字体:大 中 小] https://www.linuxidc.com/Linux/2016-02/128307.htm 早上刚百度到的 一会儿 到公司 试试 需求 最近团队正在开发一个版本对比工具,要求是把A1文件夹与A2对比,将A2中的增量部分,输出到update文件夹中,生成增量升级包/差分包. 方案研究 实现该功能的第一反应是,分别遍历2个

编程实现LINUX下目录的层层遍历

/************************************************************************* > File Name: treedir.c > Author: KrisChou > Mail:[email protected] > Created Time: Tue 19 Aug 2014 05:04:50 PM CST *****************************************************

怎样在linux下编写C程序并编译执行

一.Hello, world! 在linux下输入:(以hello.c为例)首先选中文件要保存的路径(如:cd work)vi hello.c(要编辑的文件名) 输入程序:# include<stdio.h>int main(void) { printf("hello,world!\n");   return 0;   注:return和0之间要有空格} 退出并保存程序:在vi模式下,按ESC后,按 :wq加enter键 利用gcc编译程序:(先要找到程序存在哪个文件夹中)

如何使用加多宝(jdb)在linux下调试Java程序

毕业时写了一段时间的C,那时候调试使用gdb,后来转了java,当时就想java程序怎么调试,找了一下,果然,那就是jdk自带的jdb windows里是这样的 Linux下是这样的 一般我在linux下来调试Java程序 好,那么,问题来了,这玩意怎么用?有好几种玩法 第一种玩法:以经典的HelloWorld为例,先写一个Java程序,如下: 我们把编译好的类上传到linux下,如下所示 务必强调一下:类所在的包名的层次结构也要在linux下体现出来 下面我们来玩起来,在linux下操作如下

两种在linux下创建应用程序快捷方式的方法

两种在linux下创建应用程序快捷方式的方法: A. 在桌面上创建快捷方式 B. 在应用程序菜单中添加快捷方式 在桌面上创建快捷方式 这是最简单的一种方法,在桌面上单击鼠标右键,会有一个“创建启动器”栏.这里我以为mplayer创建快捷方式为例说明: 名称-mplayer(或者你喜欢的任何名称,这个名称会出现在快捷图标的 下方) 命令-/usr/bin/gmplayer(这个是mplayer的gui应用程序的执行文件,跟 安装路径相关,可以通过which gmplayer找到) 图标-一般应用程

在linux下的使用复制命令cp,不让出现“overwrite”(文件覆盖)提示的方法。(转)

在linux下的使用复制命令cp,不让出现"overwrite"(文件覆盖)提示的方法. 一般我们在使用cp命令时加上-f选项,希望不让出现"overwrite"的提示(文件覆盖的提示).如:# cp -rf sourcefile targetdir 或#cp -r -f sourcefile targetdir-r的意思是递归复制,也就是复制文件夹及其下所有文件.-f的意思是遇到同名的文件时不提示,直接覆盖. 但是为什么加上-f了,还出现"overwri

Linux下执行Java程序

在linux下编译java程序,执行javac编译生成class文件时,在centos7终端输入如,javac hello.java    会提示未找到指令,但用java -verison测试环境变量是没问题的 百度了好久,说的很复杂,重新再linux配置环境变量,输入 vi /etc/profile进入,添加以下代码: export JAVA_HOME=/usr/local/jdk1.8.0_144 export PATH=$JAVA_HOME/bin:$PATH export CLASSPA