5

C プログラムを使用して、Linux の特定のディレクトリの正確なサイズを取得したいと考えています。statfs(path,struct statfs &) を使用してみましたが、正確なサイズがわかりません。私も stat() を試しましたが、任意の dir のサイズを 4096 として返します!

「du -sh dirPath」コマンドの後に取得するのと同じように、dir の正確なサイズを取得する方法を教えてください。

また、system() を介して du を使用したくありません。

前もって感謝します。

4

4 に答える 4

10

典型的な解決策

du と同様にディレクトリのサイズが必要な場合は、再帰関数を作成します。問題を繰り返し解くことは可能ですが、その解は再帰に向いています。

情報

開始するためのリンクは次のとおりです。

http://www.cs.utk.edu/~plank/plank/classes/cs360/360/notes/Prsize/lecture.html

探す

「stat c program recursive directory size」で Google を検索

Jim Plank の Web サイトから直接、開始するための例として役立ちます。

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

main()
{
  DIR *d;
  struct dirent *de;
  struct stat buf;
  int exists;
  int total_size;

  d = opendir(".");
  if (d == NULL) {
    perror("prsize");
    exit(1);
  }

  total_size = 0;

  for (de = readdir(d); de != NULL; de = readdir(d)) {
    exists = stat(de->d_name, &buf);
    if (exists < 0) {
      fprintf(stderr, "Couldn't stat %s\n", de->d_name);
    } else {
      total_size += buf.st_size;
    }
  }
  closedir(d);
  printf("%d\n", total_size);
}
于 2009-07-15T05:17:52.830 に答える
4

現在のディレクトリとサブディレクトリ内のすべてのファイルを stat() して合計する必要があります。

これには再帰アルゴリズムの使用を検討してください。

于 2009-07-15T05:13:03.183 に答える
2

を使用したくない'system'が、、、およびを使用'pipe'し ても問題がない場合は'fork'、パイプを作成し、新しいプロセスをフォークし、パイプ内で子をリダイレクトし、子内でexecを実行し、親で結果を読み取ることができます。サンプルコードは次のようになります。'execlp''du''STDOUT''du'

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {
  int pfd[2], n;
  char str[1000];

  if (pipe(pfd) < 0) {
    printf("Oups, pipe failed.  Exiting\n");
    exit(-1);
  }

  n = fork();

  if (n < 0) {
    printf("Oups, fork failed.  Exiting\n");
    exit(-2);
  } else if (n == 0) {
    close(pfd[0]);

    dup2(pfd[1], 1);
    close(pfd[1]);

    execlp("du", "du", "-sh", "/tmp", (char *) 0);
    printf("Oups, execlp failed.  Exiting\n"); /* This will be read by the  parent. */
    exit(-1); /* To avoid problem if execlp fails, especially if in a loop. */
  } else {
    close(pfd[1]);

    n = read(pfd[0], str, 1000); /* Should be done in a loop until read return 0, but I am lazy. */
    str[n] = '\0';

    close(pfd[0]);
    wait(&n); /* To avoid the zombie process. */

    if (n == 0) {
       printf("%s", str);
    } else {
       printf("Oups, du or execlp failed.\n");
    }
  }
}
于 2011-07-21T16:30:29.720 に答える