Chinaunix

标题: SOS!在linux下获取该目录所占磁盘空间的大小,用编程实现. [打印本页]

作者: paraller06    时间: 2006-07-29 15:14
标题: SOS!在linux下获取该目录所占磁盘空间的大小,用编程实现.
  在linux下获取该目录所占磁盘空间的大小,用编程实现.
  就像执行du 命令一样,比如:
  $du /etc/rc.d
      500     ./init.d
      4         ./rc0.d
      4         ./rc1.d
      4         ./rc2.d
      4         ./rc3.d
      4         ./rc4.d
      4         ./rc5.d   
      4         ./rc6.d
      564     .
      编程实现读到最后的数据564.
      告急!
作者: mik    时间: 2006-07-29 15:32
何不看看 du 的源代码
作者: liangxiaoailing    时间: 2006-07-29 15:45
有点意思
作者: paraller06    时间: 2006-07-29 16:21
  du的源代码看过了,试着写了.其它的一切正常,但就是总大小出错,是正确大小的两倍.
作者: paraller06    时间: 2006-07-29 16:25
标题: 我写的代码如下:
   我写的代码如下:
   #include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include <dirent.h>
#include <stdarg.h>
#include <sys/stat.h>

#ifdef CONFIG_FEATURE_HUMAN_READABLE
# ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K
static unsigned long disp_hr = 1024;
# else
static unsigned long disp_hr = 512;
# endif
#elif defined CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K
static unsigned int disp_k = 1;
#else
static unsigned int disp_k=1;        //原本是 0 现修改成1
#endif

static int max_print_depth = INT_MAX;
static int count_hardlinks = 1;               

static int status
#if EXIT_SUCCESS == 0
        = EXIT_SUCCESS
#endif
        ;
static int print_files;
static int slink_depth;
static int du_depth;
static int one_file_system;
static dev_t dir_dev;
//static int fileno[INT_MAX];

char * last_char_is(const char *s, int c)
{
        char *sret = (char *)s;
        if (sret) {
                sret = strrchr(sret, c);
                if(sret != NULL && *(sret+1) != 0)
                        sret = NULL;
        }
        return sret;
}


int bb_printf(const char * __restrict format, ...)
{
        va_list arg;
        int rv;

        va_start(arg, format);
        rv = vfprintf(stdout, format, arg);   
        va_end(arg);

        return rv;
}

static void print(long size, char *filename)
{
        /* TODO - May not want to defer error checking here. */
#ifdef CONFIG_FEATURE_HUMAN_READABLE
        bb_printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr),
                   filename);
#else
        if (disp_k) {
                size++;
                size >>= 1;
        }
        bb_printf("%ld\t%s\n", size, filename);
#endif
}

void bb_xasprintf(char **string_ptr, const char *format, ...)
{
        va_list p;
        int r;

        va_start(p, format);
        r = vasprintf(string_ptr, format, p);
        va_end(p);

}


char *concat_path_file(const char *path, const char *filename)
{
        char *outbuf;
        char *lc;
       
        if (!path)
            path="";
        lc = last_char_is(path, '/');
        while (*filename == '/')
                filename++;
        bb_xasprintf(&outbuf, "%s%s%s", path, (lc==NULL)? "/" : "", filename);

        return outbuf;
}


char *concat_subpath_file(const char *path, const char *f)
{
        if(f && *f == '.' && (!f[1] || (f[1] == '.' && !f[2])))
                return NULL;
        return concat_path_file(path, f);
}


/* tiny recursive du */
static long du(char *filename)
{
        struct stat statbuf;
        long sum;

        if ((lstat(filename, &statbuf)) != 0) {
                return 0;
        }


        sum = statbuf.st_blocks;

        if (S_ISDIR(statbuf.st_mode)) {
                DIR *dir;
                struct dirent *entry;
                char *newfile;

                dir = opendir(filename);
                if (!dir) {
                        return sum;
                }

                newfile = last_char_is(filename, '/');
                if (newfile)
                        *newfile = '\0';

                while ((entry = readdir(dir))) {
                        char *name = entry->d_name;

                        newfile = concat_subpath_file(filename, name);
                        if(newfile == NULL)
                                continue;
                        ++du_depth;
                        sum += du(newfile);
                        --du_depth;
                        free(newfile);
                }
                closedir(dir);
        } else if (du_depth > print_files) {
                return sum;
        }
       
        if (du_depth <= max_print_depth) {
                print(sum, filename);
        }
       
        return sum;
}


int main(){
        int total=0;
        total=du("/home/oyls/cache");
        printf("%d    \n",total);
        return 0;
}
作者: chenxz    时间: 2007-08-16 20:55
标题: 回复 #1 paraller06 的帖子
statfs或statvfs。
作者: barbas    时间: 2007-08-16 22:34
原帖由 paraller06 于 2006-7-29 16:25 发表
   我写的代码如下:
   #include
#include
#include
#include
#include
#include
#include

#ifdef CONFIG_FEATURE_HUMAN_READABLE
# ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K
s ...


这样递归读目录会出现问题吗?
因为用ftw时说目录多深多深时会有问题(20k层好像)




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2