【问题标题】:Printing directory: chdir not working打印目录:chdir 不工作
【发布时间】:2017-05-16 22:44:09
【问题描述】:

我想知道是否有人可以告诉我我做错了什么。这段代码应该遍历所有目录和文件,并以与 UNIX 实用程序 FIND 完全相同的方式将它们打印出来。但由于某种原因,我无法让 chdir 更改工作目录。我正在尝试限制我使用的文件描述符的数量。

主要

#include <stdio.h>
#include "sfind.h"
#include <unistd.h>
#include <dirent.h>
int main(int argv, char *argc[]){
    char cwd[1024]; /* current working directory limit*/
    char *path = NULL;
    DIR *dp = NULL;
    if (getcwd(cwd, sizeof(cwd)) != NULL){ /*allow us to grab the current working directory*/
      fprintf(stdout, "Current working dir: %s\n", cwd);
    }
    else{
        perror("getcwd() error");
    }
    dp = opendir(cwd);
    path = ".";
    directoryList(dp,path);
    return 0;
}

目录方法定义

#include <stdio.h>
#include <stdlib.h>
#include "sfind.h"
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

void directoryList(DIR *dp, char *path){
    char newPath[PATH_MAX] = {0};/*To store new path*/
  struct dirent *element; /*get file name*/
  struct stat statbuf;/*determine type of file*/
  int status = 0; /*My base case should be once the directory I'm in runs outs out of files I should return;*/
  if(dp == NULL){
    fprintf(stderr,"FILE DID NOT OPEN!");
    exit(-1);
  }
  /*change the current file directory even if its the first one*/  
  if((status = chdir(path)) == -1){
    printf("ERROOR!");
  }/*change the current working directory whether that the same on or not*/

  while((element = readdir(dp)) != NULL) /*while current file directory pointer is not equal to zero*/{ 
    /* from here we only have two cases once were reading from the directory either is a file or directory!*/
    /*using lstat*/

    lstat(element->d_name,&statbuf);

    if((S_ISDIR(statbuf.st_mode))) /*is of type directory*/{
        if((strcmp(".",element->d_name) == 0) || (strcmp("..",element->d_name) == 0))
        continue;
      /*create new directory name*/
      newPath[0] = '\0';
      strcat(newPath,path);/* this will give us the "."*/
      strcat(newPath,"/");
      strcat(newPath,element->d_name);
      printf("%s\n", newPath);
      directoryList(dp,newPath); /*recursion*/ 
      file*/
    }
    else /*Its a file!*/{
        printf("%s/%s\n",path,element->d_name);
    }
  }
}

【问题讨论】:

  • 非常感谢任何类型的帮助
  • 你看到了什么错误?
  • 我似乎无法再深入到第一个目录@Myst
  • 不只是打印ERROR!,你能用perrorstrerror打印出错误吗?
  • 一般来说,你不想在这样的函数中使用chdir()chdir() 会影响整个过程,如果你在写库或者多线程代码,那就不好了。在库代码中,您根本不想更改进程的任何状态,而在使用chdir() 的多线程代码中会影响进程中的所有线程。

标签: c


【解决方案1】:

问题似乎在于对readdir(dp)的调用...

即使您更改了当前工作目录,也不会更新dp 指针来打开新文件夹。

这是一个穷人的工作示例(我不会这样做,但它适用于小树)。

#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

void directoryList(DIR *dp, char *path) {
  char newPath[PATH_MAX] = {0}; /*To store new path*/
  struct dirent *element;       /*get file name*/
  struct stat statbuf;          /*determine type of file*/
  int status = 0;               /*My base case should be once the directory I'm in runs outs
                                   out of files I should return;*/
  DIR *dp_tmp;
  if (dp == NULL) {
    fprintf(stderr, "FILE DID NOT OPEN!");
    exit(-1);
  }

  while ((element = readdir(dp)) !=
         NULL) /*while current file directory pointer is not equal to zero*/ {
    /* from here we only have two cases once were reading from the directory
     * either is a file or directory!*/
    /*using lstat*/
    lstat(element->d_name, &statbuf);

    if ((S_ISDIR(statbuf.st_mode))) /*is of type directory*/ {
      if ((strcmp(".", element->d_name) == 0) ||
          (strcmp("..", element->d_name) == 0))
        continue;
      /*create new directory name*/
      newPath[0] = '\0';
      strcat(newPath, path); /* this will give us the "."*/
      strcat(newPath, "/");
      strcat(newPath, element->d_name);
      printf("%s\n", newPath);
      if ((dp_tmp = opendir(newPath)) == NULL) {
        perror("hmm?! ");
        exit(1);
      }
      directoryList(dp_tmp, newPath); /*recursion*/
    } else /*Its a file!*/ {
      printf("* %s/%s\n", path, element->d_name);
    }
  }
  closedir(dp);
}

int main(void) {
  char cwd[1024]; /* current working directory limit*/
  char *path = NULL;
  DIR *dp = NULL;
  if (getcwd(cwd, sizeof(cwd)) !=
      NULL) { /*allow us to grab the current working directory*/
    fprintf(stdout, "Current working dir: %s\n", cwd);
  } else {
    perror("getcwd() error");
  }
  dp = opendir(cwd);
  path = ".";
  directoryList(dp, path);
  return 0;
}

编辑:

回答评论中的问题...

打开的目录(应该使用closedir 关闭)与当前工作目录不同(并且完全不相关)。

当前工作目录主要用于解析您所引用的任何文件/文件夹的路径。

打开目录指针 (DIR *) 只是指向内存中数据的指针。该数据与特定目录相关,您可以同时打开多个目录。

EDIT2

cmets 中的一些人推荐了nftw (file tree walk),这是一个很好的选择,而不是自己做。

如果这不是一个学习项目,我会推荐它。

但是,请注意 POSIX.1-2008 将 ftw 标记为已过时,因此请务必使用 nftw 风格。

【讨论】:

  • 我以为会在while循环的条件下完成。我假设 chdir 在更改工作目录后会更新它。
  • 不。您正在更改工作目录,而不是打开目录。您可以打开任何目录,无需为此更改工作目录。
  • @SamuelMagaña,我更新了我的答案以更好地反映您的评论。
【解决方案2】:

您的目标是学习自己实现,还是只想要结果?因为如果你想要一些非常强大的东西来实现 find 之类的东西,你应该看看 fts.h。

【讨论】:

  • fts.h?你的意思是ftw.h
  • 不,但这也可以。我不完全确定哪一个更便携。
  • ftw.h is POSIXfts.h 似乎是 BSD 遗产。
猜你喜欢
  • 2011-12-13
  • 2011-01-23
  • 1970-01-01
  • 2015-04-03
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多