【问题标题】:C opening and reading directoriesC 打开和读取目​​录
【发布时间】:2016-01-04 02:01:49
【问题描述】:

所以我试图用 C 语言编写一个程序,其工作方式类似于 Linux 中的 ls 命令, 目前我已经能够列出我当前工作目录中的文件和目录,但我似乎无法对不是我的 CWD 的目录做同样的事情,我需要在开始之前更改它吗上市吗?或者函数 opendir() 是否适用于任何目录? 它必须像 Linux 中的 ls -li 一样工作,但我处理了打印的东西。 一般来说,我的程序看起来像这样(显然它有更多的东西):

void function(char *directory_to_list){

DIR *d;
struct dirent *dirp;
struct stat filestat;

 if ( (d = opendir(directory_to_list)) == NULL){
    //print error
 }
 while ( ( dirp = readdir(d) ) != NULL){
    //here i call the stat() function for every entry to get various  information
    if (stat(dirp->d_name, &filestat) == -1){
       continue;
     }
    //various prints 
 }
 closedir(d);


}

编辑:命令将是 -> ls -li [-dir] 所以如果你没有得到任何目录,你只需列出你的 CWD。​​p>

EDIT2:没有返回错误,它什么也不做,它打开目录就好了,但没有列出任何东西,所以我猜 stat 调用做得不好,还添加了我如何调用 stat() 的行。

【问题讨论】:

  • 列出密码中没有的内容是什么意思? ls -li 的目标是只列出密码中的内容。你的意思是如果你传入一个目录来列出?
  • 确切地说,命令应该是这样的: ls -li [-dir] 所以 dir 是选项,这意味着如果你不通过任何你列出你的 CWD 否则你列出你通过的目录,抱歉解释不好...
  • 当您为[-dir] 标志传递无效目录时,您能显示输出吗?那是您当前使用有效目录获得的内容吗?我认为问题可能在于您错误地使用了相对路径。
  • 现在它什么也不做,没有错误,即使我通过完整路径它什么也不做,而且显然它打开目录就好了。
  • 打印出dir->d_name。您会看到它只是一个基本文件名,而不是文件的完整路径。您需要在 d_name 前面加上完整路径或可从 CWD 到达的相对路径,并将其传递给 stat

标签: c linux directory ls


【解决方案1】:

这是一个工作版本。请特别注意不要溢出缓冲区。您必须进行一些重要的错误检查以确保安全:

#include <stdio.h>
#include <dirent.h>

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

int function(char *);

int main(void)
{
    function("/tmp");
    return 0;
}


int function(char *path)
{
    DIR *dir;
    struct dirent *dentry;
    struct stat filestat;
    char *giantbuffer = malloc(sizeof(char) * ((PATH_MAX * 2 ) + 1) );

    if ( ( dir = opendir(path) ) )
    {
         dentry = readdir(dir);
         while ( dentry )
         {

              sprintf(giantbuffer, "%s/%s", path, dentry->d_name);
              printf("%s  ", giantbuffer);

              if (stat(giantbuffer, &filestat) == 0)
                  printf("%zu\n", filestat.st_size);

              dentry = readdir(dir);
         }
         closedir(dir);
    }
    else
        return -1;

    return 0;
}

【讨论】:

  • 谢谢,为我工作,而不是在开始时使用 PATH_MAX 分配巨型缓冲区,我在 path 和 dentry->d_name 上调用了 strlen() 并添加了 + 2(用于“/”和“ \0") 并且它工作得很好,你能解释为什么需要这样做吗?当我不在 CWD 中时,我似乎不明白为什么我需要在调用 stat 之前构建完整路径。
  • Stat 需要完整的可解析路径才能找到相关文件。仅检索给定目录的名称不足以提供此功能。主要在递归循环中使用 opendir/readdir 以实现目录层次结构遍历。在这个过程中,算法实际上是相当“愚蠢”的,它通过本质上“每一次左转”递归地探索文件系统,直到探索完整个迷宫。这基本上总是建立在用户提供的原始路径之上,无论它最终变得多么复杂。
  • 在所有这些过程中,C 程序员必须手动维护完整的路径名(通常这样 stat 可以在文件上调用(但它可以用于任意数量的函数或实用程序,即递归 cp 复制) ))。要么通过系统限制预测缓冲区大小,要么像你建议的那样先测量它们并重新分配内存。两者都有缺点,后者也有时间损失系数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多