当前位置: 首页 > 面试题库 >

如何仅在C中列出一级目录?

曹子平
2023-03-14
问题内容

在终端我可以打电话给ls -d */。现在,我想要一个c程序为我做这件事,像这样:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>

int main( void )
{
    int status;

    char *args[] = { "/bin/ls", "-l", NULL };

    if ( fork() == 0 )
        execv( args[0], args );
    else
        wait( &status );

    return 0;
}

这将ls -l一切。但是,当我尝试:

char *args[] = { "/bin/ls", "-d", "*/",  NULL };

我会收到一个运行时错误:

ls:* /:没有这样的文件或目录


问题答案:

不幸的是,所有基于shell扩展的解决方案都受到最大命令行长度的限制。哪个有所不同(可以true | xargs --show- limits找出答案);在我的系统上,大约有2 MB。是的,许多人会争辩说它就足够了-一次比尔·盖茨就拥有640 KB的容量。

(在非共享文件系统上运行某些并行模拟时,在收集阶段,我有时确实在同一目录中有成千上万个文件。是的,我可以做不同的事情,但这恰恰是最简单,最可靠的方法收集数据。实际上,几乎没有POSIX实用程序足以愚蠢地假设“
X对每个人都足够”。)

幸运的是,有几种解决方案。一种是改为使用find

system("/usr/bin/find . -mindepth 1 -maxdepth 1 -type d");

您还可以根据需要设置输出的格式,而不取决于语言环境:

system("/usr/bin/find . -mindepth 1 -maxdepth 1 -type d -printf '%p\n'");

如果要排序的输出,使用\0作为分隔符(因为文件名被允许包含换行符),并-t=sort使用\0作为分隔符,太。tr会为您将它们转换为换行符:

system("/usr/bin/find . -mindepth 1 -maxdepth 1 -type d -printf '%p\0' | sort -t= | tr -s '\0' '\n'");

如果要在数组中使用名称,请改用glob()function。

最后,就像我不时地竖琴一样,可以使用POSIX nftw()函数在内部实现此功能:

#define _GNU_SOURCE
#include <stdio.h>
#include <ftw.h>

#define NUM_FDS 17

int myfunc(const char *path,
           const struct stat *fileinfo,
           int typeflag,
           struct FTW *ftwinfo)
{
    const char *file = path + ftwinfo->base;
    const int depth = ftwinfo->level;

    /* We are only interested in first-level directories.
       Note that depth==0 is the directory itself specified as a parameter.
    */
    if (depth != 1 || (typeflag != FTW_D && typeflag != FTW_DNR))
        return 0;

    /* Don't list names starting with a . */
    if (file[0] != '.')
        printf("%s/\n", path);

    /* Do not recurse. */
    return FTW_SKIP_SUBTREE;
}

nftw()使用上面的电话显然是这样的

if (nftw(".", myfunc, NUM_FDS, FTW_ACTIONRETVAL)) {
    /* An error occurred. */
}

唯一的 “问题”
的使用nftw()是选择文件描述符的函数可以使用的一个好数字(NUM_FDS)。POSIX说,一个进程必须始终能够至少有20个打开文件描述符。如果我们减去标准的(输入,输出和错误),则剩下的是17。但是,上面的值不太可能使用超过3。

您可以使用找到实际限制sysconf(_SC_OPEN_MAX),然后减去您的进程可能同时使用的描述符数量。在当前的Linux系统中,每个进程通常限制为1024。

消息是,只要该数字至少为4或5,那么它只会影响性能:它仅决定nftw()必须使用变通办法之前目录树结构的深度。

如果要创建包含许多子目录的测试目录,请使用以下Bash之类的方法:

mkdir lots-of-subdirs
cd lots-of-subdirs
for ((i=0; i<100000; i++)); do mkdir directory-$i-has-a-long-name-since-command-line-length-is-limited ; done

在我的系统上,正在运行

ls -d */

在该目录中会产生bash: /bin/ls: Argument list too long错误,而find命令和nftw()基于程序都可以正常运行。

同样,您也无法使用删除目录rmdir directory-*/。采用

find . -name 'directory-*' -type d -print0 | xargs -r0 rmdir

代替。或者只是删除整个目录和子目录,

cd ..
rm -rf lots-of-subdirs


 类似资料:
  • 问题内容: 我希望仅列出某个文件夹内的目录。这意味着我既不想列出文件名,也不需要其他子文件夹。 让我们看看一个例子是否有帮助。在当前目录中,我们有: 但是,我不想列出文件名。我也不需要子文件夹,例如\ Lib \ curses。本质上,我想要的东西适用于以下情况: 但是,我想知道是否有一种更简单的方法来获得相同的结果。我得到的印象是仅使用os.walk返回顶级是无效/太多的。 问题答案: 使用os

  • 问题内容: 我需要在C编程中递归列出所有目录和文件。我已经研究了FTW,但是我所使用的2个操作系统(Fedora和Minix)中没有包括。在过去的几个小时中,我从阅读的所有不同内容中开始感到头疼。 如果有人知道我的代码片段,那真是太棒了,或者如果有人可以给我很好的指导,我将不胜感激。 问题答案: 这是一个递归版本:

  • 在我的例子中,我有许多子项目和子/子项目的多项目构建。 然后,我希望能够从不同的子项目调用此任务,以生成不同的JAR集(基于项目依赖关系)。这样我就可以为不同的子项目创建单独的分布。 我已经到了可以以一种丑陋的方式列出所有项目DEP JAR的阶段: 我正在执行一项任务,将所有项目jar收集在一个目录中,以创建应用程序的分发。有什么干净的方法来实现这一点吗? 谢谢!

  • 我很久以前就问过这个问题.... 有没有办法在Gradle中列出任务依赖关系?

  • 问题内容: 在Python中,我只想列出当前目录中的所有文件。我不希望从任何子目录或父目录中列出文件。 似乎确实有类似的解决方案,但它们似乎对我不起作用。这是我的代码段: 假设我在当前目录中有2个文件holygrail.py和Tim。我也有一个文件夹,其中包含两个文件- 我们称它们为Arthur和Lancelot。当我运行脚本时,这就是我得到的: 我对holygrail.py和Tim感到满意。但是

  • 在Python中,我只想列出当前目录中的所有文件。我不想从任何子目录或父目录中列出文件。 似乎也有类似的解决方案,但它们似乎不适合我。以下是我的代码片段: 假设我有两个文件,holygrail.py和蒂姆在我的当前目录。我也有一个文件夹,里面有两个文件——让我们称之为亚瑟和兰斯洛特。当我运行脚本时,这是我得到的: 我对holygrail.py和蒂姆很满意。但是亚瑟和兰斯洛特这两个文件,我不想列出来