Как настроить имя домена для локального сервера SchoolTool

Я написал эту утилиту, которая должна работать довольно быстро, вот результат в моем домашнем каталоге для запуска по умолчанию:

??? 3897697700  (717MiB)
.tgz    1550090721  (1478MiB)
.jpg    872736861   (832MiB)
.iso    804329472   (767MiB)
.pack   636183905   (606MiB)
.gch    528345920   (503MiB)
.d  384725346   (366MiB)
.i  354098997   (337MiB)
.sqlite 302110738   (288MiB)
.html   233729943   (222MiB)
.cs 209534627   (199MiB)
.dll    198655123   (189MiB)
.xml    192561101   (183MiB)
.pdf    184729508   (176MiB)
.deb    173972838   (165MiB)

Обратите внимание, что большая запись ??? связана с множеством. hg и .git, которые не имеют расширений.

По умолчанию используется код для печати самых популярных файлов типа top-15, хотя это может быть легко расширено.

В коде используется код TODO для использования libmagic, чтобы получить фактический filetypes.

Вот код:

#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <cstdio>
#include <cstdlib>
#include <stdint.h>

#include <set>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>

static uintmax_t total        = 0ul;
static uintmax_t files        = 0ul;
static uintmax_t directories  = 0ul;
static uintmax_t symlinks     = 0ul;
static uintmax_t inaccessible = 0ul;
static uintmax_t blocks512    = 0ul;

struct byfiletype {
    std::string filetype;
    mutable uintmax_t total; // non-key

    bool operator<(const byfiletype& other) const { return filetype<other.filetype; }
    static bool largest_first(const byfiletype& a, const byfiletype& b) { return a.total>b.total; }
};

typedef std::set<byfiletype> sizemap;
static sizemap per_filetype;

std::string get_filetype(std::string fname) // TODO use libmagic to do file type detection?
{
    size_t pos = fname.rfind("/");
    if (std::string::npos != pos) fname = fname.substr(pos+1);

    pos = fname.rfind(".");

    return (std::string::npos != pos)
        ? fname.substr(pos)
        : "???";
}

static int
display_info(const char *fpath, const struct stat *sb,
             int tflag, struct FTW *ftwbuf)
{
    switch(tflag)
    {
        case FTW_D:
        case FTW_DP:  directories++;  break;
        case FTW_NS:
        case FTW_SL:
        case FTW_SLN: symlinks++;     break;
        case FTW_DNR: inaccessible++; break;
        case FTW_F:   
                      files++; 
                      byfiletype entry = { get_filetype(fpath), sb->st_size };
                      sizemap::iterator match = per_filetype.find(entry);

                      if (match != per_filetype.end()) 
                          match->total += sb->st_size;
                      else 
                          per_filetype.insert(entry);

                      break;
    }
    total += sb->st_size;
    blocks512 += sb->st_blocks;
    return 0; /* To tell nftw() to continue */
}

int
main(int argc, char *argv[])
{
    int flags = FTW_DEPTH | FTW_MOUNT | FTW_PHYS;

    if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags) == -1)
    {
        perror("nftw");
        exit(EXIT_FAILURE);
    }

    printf("Total size: %7jd\n", total);
    printf("In %jd files and %jd directories (%jd symlinks and %jd inaccessible directories)\n", files, directories, symlinks, inaccessible);
    printf("Size on disk %jd * 512b = %jd\n", blocks512, blocks512<<9);

    size_t N = std::min(15ul, per_filetype.size());
    typedef std::vector<byfiletype> topN_t;
    topN_t topN(N);
    std::partial_sort_copy(
            per_filetype.begin(), per_filetype.end(),
            topN.begin(), topN.end(),
            byfiletype::largest_first);

    for (topN_t::const_iterator it=topN.begin(); it!=topN.end(); ++it)
    {
        std::cout << it->filetype << "\t" << it->total << "\t(" << ((it->total)>>20) << "MiB)" << std::endl;
    }

    exit(EXIT_SUCCESS);
}
2
задан 30 November 2011 в 08:26

0 ответов

Другие вопросы по тегам:

Похожие вопросы: