如何在C中遍历目录

时间:2010-02-07 17:18:27

标签: c gtk glib directory-walk

我在我的应用程序中使用了glib,我发现在gl的C removeunlinkrmdir中有一些便利包装器。但是这些只能在一个文件或目录上工作。

据我所知,C标准和glib都不包含任何类型的递归目录遍历功能。我也没有看到一次删除整个目录树的具体方法,就像使用rm -rf一样。

对于我正在做的事情,我并不担心任何复杂的问题,例如权限,符号链接备份树(无限递归),或任何会排除非常天真的事情 实现...所以我不反对为它编写我自己的函数。

但是,我很好奇这个功能是否已经出现在标准库gtk或glib(或其他一些容易重用的C库)的某处,我只是没有偶然发现它。谷歌搜索这个主题会产生很多错误的线索。

否则我的计划是使用这种算法:

dir_walk(char* path, void* callback(char*) {
  if(is_dir(path) && has_entries(path)) {
    entries = get_entries(path);
    for(entry in intries) { dir_walk(entry, callback); }
  }
  else { callback(path) }
}

dir_walk("/home/user/trash", remove);

显然,如果遇到致命错误,我会建立一些错误处理等来中止进程。

5 个答案:

答案 0 :(得分:7)

你看过<dirent.h>了吗? AFAIK属于POSIX规范,它应该是大多数(如果不是全部)C编译器的标准库的一部分。参见例如this <dirent.h> reference (Single UNIX specification Version 2 by the Open Group)

P.S。,在有人对此发表评论之前:不,这不提供递归目录遍历。但后来我认为这最好是由开发人员实现的;需求可以有很大不同,所以一个适合所有的递归遍历函数必须非常强大。 (例如:符号链接是否跟进?是否应该限制递归深度?等等)

答案 1 :(得分:5)

几个平台包括ftw和nftw:“(新)文件树步行”。检查imac上的手册页显示这些是遗留的,新用户应该更喜欢fts。可移植性可能是这些选择中的任何一个的问题。

答案 2 :(得分:4)

如果您想使用glib,可以使用GFileEnumerator

答案 3 :(得分:2)

标准C库旨在提供原始功能。你在谈论的是复合行为。您可以使用所选API中的低级功能轻松实现它 - take a look at this tutorial

答案 4 :(得分:-1)

请注意,你提到的remove(),unlink()和rmdir()的“便利包装器”,假设你指的是在&lt; glib / gstdio.h&gt;中声明的那些,并不是真正的“便利包装器”。使用“g_”为完全标准函数添加前缀的便利是什么? (请注意,即使我首先介绍了它们,我也会这样说。)

这些包装器存在的唯一原因是Windows上的文件名问题,其中这些包装器实际上由实际代码组成;它们采用Unicode格式的文件名参数,以UTF-8编码。相应的“未解包”Microsoft C库函数在系统代码页中获取文件名。

如果您没有专门编写可移植到Windows的代码,则没有理由使用g_remove()etc包装器。