【问题标题】:Unexpected Results using fts_children() in C在 C 中使用 fts_children() 的意外结果
【发布时间】:2012-09-27 15:38:48
【问题描述】:

对于这个 fts_children() 问题,我一直在敲我的头。在手册页中,http://www.kernel.org/doc/man-pages/online/pages/man3/fts.3.html,它明确指出As a special case, if fts_read() has not yet been called for a hierarchy, fts_children() will return a pointer to the files in the logical directory specified to fts_open(), that is, the arguments specified to fts_open(). 我的意思是返回当前目录中所有文件的链接列表。好吧,我发现情况并非如此,我非常感谢在这件事上提供一些帮助。我希望返回一个链接列表,然后我会遍历它以找到具有匹配文件名的文件(最终目标)。但是,现在,我只是想遍历链表(小步骤)。现在,它将返回一个文件,然后退出循环。这对我来说没有意义。任何帮助将不胜感激!!!

打开文件系统:

char* const path[PATH_MAX] = {directory_name(argv[argc-index]), NULL}; 
            char* name = file_name(argv[argc-index]);

            if ((file_system = fts_open(path, FTS_COMFOLLOW, NULL)) == NULL){
                fprintf(stderr,"%s:%s\n", strerror(errno), getprogname());
                        exit(EXIT_FAILURE);
                 }/*Ends the files system check if statement*/

            /*Displays the information about the specified file.*/
            file_ls(file_system,name, flags);

为澄清起见,directory_name 解析用户输入的路径并返回类似 /home/tpar44 的内容。然后打开该目录。

在文件系统中搜索:

void
file_ls(FTS* file_system, char* file_name,  int* flags){
    FTSENT* parent = NULL;
    //dint stop = 0;

    parent = fts_children(file_system, 0);

    while( parent != NULL ){
        printf("parent = %s\n", parent->fts_name);
        parent = parent->fts_link;
    }
}

谢谢!

【问题讨论】:

  • char* const path[PATH_MAX] = {directory_name(argv[argc-index]), NULL}; - 这是一个 PATH_MAX c 样式字符串的数组,但只填充了 2 个条目,第二个 NULL?
  • @sehe 它实际上是一个二维数组,不是吗?我必须将 fts_open 的文件系统变量设为 char* const* 所以我就是这样做的。我知道它很糟糕,但我不知道如何使用它。此外,第二个参数为 NULL 以防止迭代结束。
  • 还不错,但使用 PATH_MAX 显示混乱。更好的是,您可以将其省略,因为初始化程序将允许编译器推断数组大小。 (除其他事项外,我已经发布了一个答案)

标签: c linux filesystems system-calls traversal


【解决方案1】:

我认为这完全是设计使然。

...即指定给fts_open()的参数...

它的意思是为了您的方便,它将列出path_argv 参数中的根元素。它将path_argv 数组本身视为一个逻辑目录

换句话说:

int main(int argc, char* const argv[])
{
    char* const path[] = { ".", "/home", "more/root/paths", NULL }; 

    FTS* file_system = fts_open(path, FTS_COMFOLLOW | FTS_NOCHDIR, &compare);

    if (file_system)
    {
        file_ls(file_system, "", 0);
        fts_close(file_system);
    }
    return 0;
}

会输出

parent = .
parent = /home
parent = more/root/paths

事实上,确实如此(参见http://liveworkspace.org/code/c2d794117eae2d8af1166ccd620d29eb)。

这是一个更完整的示例,显示了完整的目录遍历:

#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fts.h>
#include<string.h>
#include<errno.h>

int compare (const FTSENT**, const FTSENT**);

void file_ls(FTS* file_system, const char* file_name, int* flags)
{
    FTSENT* node = fts_children(file_system, 0);

    if (errno != 0)
        perror("fts_children");

    while (node != NULL)
    {
        // TODO use file_name and flags
        printf("found: %s%s\n", node->fts_path, node->fts_name);
        node = node->fts_link;
    }
}

int main(int argc, char* const argv[])
{
    FTS* file_system = NULL;
    FTSENT* node = NULL;

    if (argc<2)
    {
        printf("Usage: %s <path-spec>\n", argv[0]);
        exit(255);
    }

    char* const path[] = { argv[1], NULL }; 
    const char* name = "some_name";

    file_system = fts_open(path, FTS_COMFOLLOW | FTS_NOCHDIR, &compare);

    if (file_system)
    {
        file_ls(file_system, name, 0); // shows roots

        while( (node = fts_read(file_system)) != NULL)
            file_ls(file_system, name, 0); // shows child elements

        fts_close(file_system);
    }
    return 0;
}

int compare(const FTSENT** one, const FTSENT** two)
{
    return (strcmp((*one)->fts_name, (*two)->fts_name));
}

【讨论】:

  • 非常感谢您的帮助。显然我有一个问题,那就是把事情复杂化到极致。我真的没有必要推断出文件所在的路径和名称。我实际上已经准备好了所有的部分,我只是把问题分解得太久了。非常感谢!!!!
  • 所有其他在线 fts 示例在不同环境中使用时都会产生疯狂/随机的结果。例如,在 Eclipse 中,一个示例导致 fts 在我的整个系统中搜索包含文件的文件夹,这些文件夹的名称与我实际想要遍历的文件夹中的文件名称相同 0_0
  • @Serge 可能的罪魁祸首:符号链接(连接点、重解析点等)。人们认为文件系统是树......我注意到我可能应该明确地将FTS_PHYSICAL 传递给fts_open。还可以查看FTS_XDEV 以防止遍历挂载点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 2022-10-14
  • 2021-12-20
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多