免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5833 | 回复: 6
打印 上一主题 下一主题

SOS!在linux下获取该目录所占磁盘空间的大小,用编程实现. [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-07-29 15:14 |只看该作者 |倒序浏览
  在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.
      告急!

论坛徽章:
0
2 [报告]
发表于 2006-07-29 15:32 |只看该作者
何不看看 du 的源代码

论坛徽章:
0
3 [报告]
发表于 2006-07-29 15:45 |只看该作者
有点意思

论坛徽章:
0
4 [报告]
发表于 2006-07-29 16:21 |只看该作者
  du的源代码看过了,试着写了.其它的一切正常,但就是总大小出错,是正确大小的两倍.

论坛徽章:
0
5 [报告]
发表于 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;
}

论坛徽章:
0
6 [报告]
发表于 2007-08-16 20:55 |只看该作者

回复 #1 paraller06 的帖子

statfs或statvfs。

论坛徽章:
0
7 [报告]
发表于 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层好像)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP