在 Linux 上使用 C 检查目录是否为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6383584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:35:30  来源:igfitidea点击:

Check if a directory is empty using C on Linux

clinuxdirectory

提问by freethinker

Is this the right way of checking whether a directory is empty or not in C? Is there a more efficient way to check for an empty directory, especially if it has 1000s of files if not empty?

这是在 C 中检查目录是否为空的正确方法吗?有没有更有效的方法来检查空目录,特别是如果它有 1000 个文件(如果不是空的)?

int isDirectoryEmpty(char *dirname) {
  int n = 0;
  struct dirent *d;
  DIR *dir = opendir(dirname);
  if (dir == NULL) //Not a directory or doesn't exist
    return 1;
  while ((d = readdir(dir)) != NULL) {
    if(++n > 2)
      break;
  }
  closedir(dir);
  if (n <= 2) //Directory Empty
    return 1;
  else
    return 0;
}

If its an empty directory, readdirwill stop after the entries '.' and '..' and hence empty if n<=2.

如果它是一个空目录,readdir将在条目 '.' 之后停止。和 '..' 因此是空的 if n<=2

If its empty or doesn't exist, it should return 1, else return 0

如果它为空或不存在,则应返回 1,否则返回 0

Update:

更新:

@c$ time ./isDirEmpty /fs/dir_with_1_file; time ./isDirEmpty /fs/dir_with_lots_of_files
0

real    0m0.007s
user    0m0.000s
sys 0m0.004s

0

real    0m0.016s
user    0m0.000s
sys 0m0.008s

Why does it take longer to check for a directory with lots of files as compared to one with just one file?

为什么与只有一个文件的目录相比,检查包含大量文件的目录需要更长的时间?

采纳答案by cnicutar

Is there a more efficient way to check for an empty directory, especially if it has 1000s of files if not empty

有没有更有效的方法来检查空目录,特别是如果它有 1000 个文件,如果不是空的

The way you wrote your code it doesn't matter how many files it has (you breakif n > 2). So your code is using a maximum of 5 calls. I don't think there's any way to (portably) make it faster.

您编写代码的方式与它有多少个文件无关(break如果 n > 2,则为您)。所以你的代码最多使用 5 个调用。我认为没有任何方法可以(可移植地)使其更快。

回答by Dawson

bool has_child(string path)
{
    if(!boost::filesystem::is_directory(path))
        return false;

    boost::filesystem::directory_iterator end_it;
    boost::filesystem::directory_iterator it(path);
    if(it == end_it)
        return false;
    else
        return true;
}

回答by kato2

Maybe this code could help you:

也许此代码可以帮助您:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char *cmd;
    char *folder = "/tmp";
    int status, exitcode;
    char *format="test $(ls -AU \"%s\" 2>/dev/null | head -1 | wc -l) -ne 0";
    clock_t start, stop;
    int size;

    if(argc == 2)
            folder = argv[1];

    size = strlen(format)+strlen(folder)+1;
    cmd = malloc(size * sizeof(char));

    snprintf(cmd, size, format, folder);
    printf("executing: %s\n", cmd);

    status = system(cmd);
    exitcode = WEXITSTATUS(status);

    printf ("exit code: %d, exit status: %d\n", exitcode, status);

    if (exitcode == 1)
            printf("the folder is empty\n");
    else
            printf("the folder is non empty\n");

    free(cmd);
    return 0;
}

I check if the folder is empty using ls -AU folder 2>/dev/null | head -1 | wc -l, to count the files in the folder, if it returns zero the folder is empty else the folder is non empty. The WEXITSTATUS macro, returns the exit code of the executed command. head command doesn't wait until ls finish, just until the condition is fit.

我使用 ls -AU folder 2>/dev/null | 检查文件夹是否为空 头-1 | wc -l,计算文件夹中的文件数,如果返回零,则该文件夹为空,否则该文件夹为非空。WEXITSTATUS 宏,返回已执行命令的退出代码。head 命令不会等到 ls 完成,直到条件合适。

some examples using the find command to generate long file list show that it is really effective

一些使用 find 命令生成长文件列表的例子表明它确实有效

Command without head

无头命令

/usr/bin/time -p -v find / -print | wc -l

output
Command being timed: "find / -print"
    User time (seconds): 0.63
    System time (seconds): 1.28
    Percent of CPU this job got: 98%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.94
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 6380
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 3419
    Voluntary context switches: 7
    Involuntary context switches: 140
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Files counted: 1043497

Command modified using head

使用 head 修改的命令

/usr/bin/time -p -v find / -print | head -1 | wc -l

Command terminated by signal 13
    Command being timed: "find / -print"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 100%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 2864
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 136
    Voluntary context switches: 1
    Involuntary context switches: 0
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Files counted: 1

As you can see while the first command without "head" tooks 1.28 seconds for execution the command modified with "head" tooks 0 seconds for execution.

正如您所看到的,第一个没有“head”的命令执行时间为 1.28 秒,而使用“head”修改的命令执行时间为 0 秒。

Moreover if we measure the execution time of the above core, with and without head we have.

此外,如果我们测量上述核心的执行时间,我们有和没有头。

Normal ls:

正常 ls:

/usr/bin/time -p ls -A /var/lib/dpkg/info/
real 0.67
user 0.06
sys 0.06

program without head

无头程序

/usr/bin/time -p ./empty.exe /var/lib/dpkg/info/
executing: test $(ls -AU "/var/lib/dpkg/info/" 2>/dev/null | wc -l) -ne 0
exit code: 0, exit status: 0
the folder is non empty
real 0.01
user 0.00
sys 0.01

program using head

使用 head 的程序

/usr/bin/time -p ./empty.exe /var/lib/dpkg/info/
executing: test $(ls -AU "/var/lib/dpkg/info/" 2>/dev/null | head -1 | wc -l) -ne 0
exit code: 0, exit status: 0
the folder is non empty
real 0.00
user 0.00
sys 0.00

Note: if the folder doesn't exists, or you don't have the correct permissions to access it, this program must print "the folder is empty".

注意:如果文件夹不存在,或者您没有正确的访问权限,该程序必须打印“文件夹为空”。

The program was built using: gcc empty.c -o empty.exe

该程序是使用以下方法构建的:gcc empty.c -o empty.exe