写简单的杜克隆。获取子目录中文件大小的随机值。

时间:2011-12-31 03:40:53

标签: c recursion sum filesize directory

我正在尝试编写一个基本程序,它将总结当前目录和所有子目录中所有文件的文件大小。我认为这将是一个很好的练习。我正在尝试使用基本递归。以下是我到目前为止的情况:

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

long totalbytes = 0;

long dirsize(const char* directory, int verbose)
{
  struct dirent *de;
  struct stat s;
  DIR * dir; 
  //long total_items = 0;
  long filesize = 0;

  dir = opendir(directory);
  if (dir == NULL)
  {
     printf("Failed to open %s.\n", directory);
     return -1;
  }

  while ((de = readdir (dir)) != NULL)
  {
    stat(de->d_name, &s);
  if (S_ISLNK(s.st_mode)) 
  {
    printf("links are ignored.\n");
  }
  if (de->d_type == DT_REG)
  {
    filesize = 0; //be sure to reset this each time to avoid inaccuracy
    stat(de->d_name, &s); // get file info into our s structure
    if (verbose) 
    {
      printf("%s/%s : %ld bytes (%f MB)\n", directory, de->d_name, s.st_size, (float) s.st_size / 1024 / 1024);
    }
    filesize = s.st_size; //put file size into filesize variable
    totalbytes += filesize; //increment totalbytes
  }
  if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
  {
    char pathname[PATH_MAX];
    sprintf(pathname, "%s/%s", directory, de->d_name);
    dirsize(pathname, verbose); //recursion: keep looping until no more subdirs remain
    }
  }
  closedir(dir);
  return totalbytes;
}

long compute_size(const char* directory, int verbose)
{
  long space = dirsize(directory, verbose);
  return space;
}

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    printf("Usage: dirsize DIRECTORY\n");
return -1;
  }

  int verbose = 1; //show or hide individual computations

  long space = compute_size(argv[1], verbose);
  if (space != -1)
  {
    float space_mb = (float) space / 1024 / 1024;
    printf("space occupied: %ld bytes\n", space);
    printf("(%f MB)\n", space_mb);
  }
  return 0;
}

这是我的程序输出(我还包括子目录的ls)

08:35 PM@~/tmp$ ./dirsize .
./dirsize : 8369 bytes (0.007981 MB)
./diskstat.c : 1430 bytes (0.001364 MB)
./diskstat : 7993 bytes (0.007623 MB)
./ftw.c : 491 bytes (0.000468 MB)
./a.out : 8044 bytes (0.007671 MB)
./arrays.sh : 212 bytes (0.000202 MB)
./fileread/timestamp : 0 bytes (0.000000 MB)
./fileread/timestamp.c : 0 bytes (0.000000 MB)
./fileread/a.out : 8044 bytes (0.007671 MB)
./fileread/build.prop : 8044 bytes (0.007671 MB)
./fileread/read.c : 4096 bytes (0.003906 MB)
./fileread/read : 454656 bytes (0.433594 MB)
./local.fstab : 76 bytes (0.000072 MB)
./dirsize.c : 1857 bytes (0.001771 MB)
./echo.sh : 223 bytes (0.000213 MB)
./TEAMS.sh : 605 bytes (0.000577 MB)
space occupied: 504140 bytes
(0.480785 MB)
08:35 PM@~/tmp$ ls -l fileread/
total 40
-rwxr-xr-x 1 raidzero raidzero 8132 Dec 28 10:39 a.out
-rw-r--r-- 1 raidzero raidzero 2346 Dec 28 10:09 build.prop
-rwxr-xr-x 1 raidzero raidzero 8384 Dec 29 13:57 read
-rw-r--r-- 1 raidzero raidzero 1150 Dec 28 10:16 read.c
-rwxr-xr-x 1 raidzero raidzero 8132 Dec 29 13:57 timestamp
-rw-r--r-- 1 raidzero raidzero  659 Dec 28 10:39 timestamp.c
08:35 PM@~/tmp$

在我有限的经验中,获取随机数据是内存分配不正确的标志,但stat结构中的st_size是一个long int ..?

1 个答案:

答案 0 :(得分:2)

de->d_name只有文件名 - 它不包含通向它的路径。因此,您要定位./timestamp而不是./fileread/timestamp。您可以构建文件的完整路径,使用chdir()随意输入目录(如果您处于多线程环境中则不安全,如果在您进入时移动目录,则可能很脆弱它们 - fchdir()对于返回更高级目录非常有用),或者(在最近的unixen上)使用openat() / fstat()函数来遍历目录。

请注意,如果您检查了stat的错误返回,您会注意到这一点。始终检查这些错误返回。