Dies ist eine Fortsetzung von Letztes Mal. Wir werden die Implementierung des Befehls du weiterhin verfolgen.
Ich werde die du_files ()
, die ich das letzte Mal gesehen habe, erneut veröffentlichen.
python
/* Recursively print the sizes of the directories (and, if selected, files)
named in FILES, the last entry of which is NULL.
BIT_FLAGS controls how fts works.
Return true if successful. */
static bool
du_files (char **files, int bit_flags)
{
bool ok = true;
if (*files)
{
FTS *fts = xfts_open (files, bit_flags, NULL); //(1)
while (1)
{
FTSENT *ent;
ent = fts_read (fts); //(2)
if (ent == NULL)
{
if (errno != 0)
{
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
FTS_CROSS_CHECK (fts);
ok &= process_file (fts, ent); //(3)
}
if (fts_close (fts) != 0)
{
error (0, errno, _("fts_close failed"));
ok = false;
}
}
return ok;
}
Die hier durchgeführte Verarbeitung ist die folgenden drei.
(1). Holen Sie sich die FTS-Struktur aus dem Dateinamen mit xfts_open ()
.
(2) Holen Sie sich die FTSENT-Struktur aus der FTS-Struktur mit fts_read ()
. --- Bis zum letzten Mal
(3) Rufen Sie "process_file ()" auf und kehren Sie zu (2) zurück.
Die Figur ist wie folgt.
Dieses Mal werden wir uns process_file ()
in (3) ansehen.
process_file()
python
static bool
process_file (FTS *fts, FTSENT *ent)
{
bool ok = true;
struct duinfo dui;
struct duinfo dui_to_print;
size_t level;
static size_t prev_level;
static size_t n_alloc;
static struct dulevel *dulvl;
const char *file = ent->fts_path;
const struct stat *sb = ent->fts_statp;
//Fortsetzen
Schauen wir uns die Variablen an.
dui
: Aktuelle Verzeichnisinformationen. Das Größenfeld enthält die Gesamtgröße der Dateien im Verzeichnis.
dui_to_print
: Verzeichnisinformationen zur Anzeige. Informationen, die auf dem Bildschirm angezeigt werden, wenn der Befehl du ausgeführt wird.
level
: Die Tiefe der aktuellen Dateihierarchie.
prev_level
: Die Tiefe der vorherigen Dateihierarchie.
n_alloc
: Ein Parameter, der zum Zuweisen von dulvl
verwendet wird. Stellen Sie einen Wert ein, der größer als die Tiefe der Dateihierarchie ist.
dulvl
: Ein Array mit Verzeichnisinformationen. Die Tiefe der Dateihierarchie entspricht dem Index des Arrays. Zum Beispiel entsprechen die Informationen im Verzeichnis in Tiefe 2 dulvl [2]. Die Felder der Dulevel-Struktur sind:
struct duinfo ent
: Verzeichnisinformationen ohne Unterverzeichnisse.
struct duinfo subdir
: Verzeichnisinformationen für Unterverzeichnisse.
Das Feld size
von ent
ist die Größe der Datei unter dem Verzeichnis. Die Dateigröße unter dem Unterverzeichnis ist jedoch ausgeschlossen.
Andererseits enthält das Feld "Größe" von "Unterverzeichnis" die Dateigröße unter dem Unterverzeichnis.
Mit anderen Worten, die Summe aus "Größe" von "ent" und "Unterverzeichnis" ergibt die Dateigröße einschließlich der Unterverzeichnisse unter dem Verzeichnis.
file
: Der Stammpfad der Datei.
sb
: Ein Zeiger auf die Statistikstruktur. Holen Sie sich die Dateigröße von hier.
duinfo_set()
Rufen Sie dann duinfo_set ()
auf.
python
duinfo_set (&dui,
(apparent_size
? MAX (0, sb->st_size)
: (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
(time_type == time_mtime ? get_stat_mtime (sb)
: time_type == time_atime ? get_stat_atime (sb)
: get_stat_ctime (sb)));
python
static inline void
duinfo_set (struct duinfo *a, uintmax_t size, struct timespec tmax)
{
a->size = size;
a->inodes = 1;
a->tmax = tmax;
}
duinfo_set ()
ist eine Funktion, die die Dateigröße und den Zeitstempel im ersten Argument dui
festlegt.
scheinbar_size
ist ein Flag, das die tatsächliche Dateigröße und nicht die Festplattennutzung ausgibt. Die Datenträgerverwendung einer Datei ist die Dateigröße, die auf die Blockgröße des Dateisystems aufgerundet wird.
Wenn die Blockgröße beispielsweise 4 KByte und die Dateigröße 8,5 KByte beträgt, beträgt die Festplattennutzung 12 KByte. Der Befehl du zeigt standardmäßig die Festplattennutzung an.
Wenn scheinbar_size
wahr ist, wird die tatsächliche Dateigröße an das Argument von duinfo_set ()
übergeben, und wenn es falsch ist, wird die Blockverwendung übergeben.
Die Dateigröße wurde in dui
von duinfo_set ()
festgelegt.
Siehe den nächsten Prozess.
python
level = ent->fts_level;
dui_to_print = dui;
Geben Sie die Tiefe der Dateihierarchie in "Ebene" ein. Setze auch dui_to_print
.
Der nächste Schritt besteht darin, die Dateigröße "dui" zur Verzeichnisgröße hinzuzufügen. Die Verarbeitung ist in die folgenden drei Muster unterteilt.
python
prev_level = level;
if (! (opt_separate_dirs && IS_DIR_TYPE (info)))
duinfo_add (&dulvl[level].ent, &dui);
duinfo_add (&tot_dui, &dui);
Fügen Sie zunächst die Dateigröße von dui
zu duvlv [level] .ent
hinzu. dulvl [level]
ist eine Struktur, die Informationen über Verzeichnisse in der Tiefe level
verarbeitet. Hier wird die Gesamtdateigröße derselben Hierarchie berechnet. Beachten Sie, dass "opt_separate_dirs" eine Option ist, die die Größe des Unterverzeichnisses nicht enthält, und "IS_DIR_TYPE (ent-> fts_info)" wahr ist, wenn die angezeigte Datei ein Verzeichnis ist. Das heißt, wenn Sie keine Unterverzeichnisse einschließen, wird die Größe der Verzeichnisse nicht hinzugefügt.
Als nächstes fügen Sie die Dateigröße auch zu "tot_dui" hinzu. tot_dui
ist die Summe aller Dateigrößen.
python
size_t i;
for (i = prev_level + 1; i <= level; i++)
{
duinfo_init (&dulvl[i].ent);
duinfo_init (&dulvl[i].subdir);
}
prev_level = level;
if (! (opt_separate_dirs && IS_DIR_TYPE (info)))
duinfo_add (&dulvl[level].ent, &dui);
duinfo_add (&tot_dui, &dui);
Wenn Sie die Dateihierarchie durchgehen, befinden Sie sich zum ersten Mal in diesem Verzeichnis. Initialisieren Sie also "dulvl [i]" mit "duinfo_init ()". Der Rest des Prozesses ist der gleiche wie zuvor.
python
duinfo_add (&dui_to_print, &dulvl[prev_level].ent);
if (!opt_separate_dirs)
duinfo_add (&dui_to_print, &dulvl[prev_level].subdir);
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].ent);
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].subdir);
prev_level = level;
if (! (opt_separate_dirs && IS_DIR_TYPE (ent->fts_info)))
duinfo_add (&dulvl[level].ent, &dui);
duinfo_add (&tot_dui, &dui);
Wenn Sie die Dateihierarchie aufrufen, ist der vorherige Speicherort das aktuelle Unterverzeichnis. Fügen Sie daher die Kapazität des vorherigen Verzeichnisses zu "dui_to_print" und "dulvl [level] .subdir" hinzu.
Wenn es sich bei der angezeigten Datei um ein Verzeichnis handelt, wird die Verzeichniskapazität angezeigt.
python
if ((IS_DIR_TYPE (ent->fts_info) && level <= max_depth)
|| ((opt_all && level <= max_depth) || level == 0))
print_size (&dui_to_print, file);
Dies ist das erste Mal, dass ich den Quellcode eines Befehls lese, aber es wird auch Anfängern empfohlen, da der Code nicht lang ist und das Funktionsprinzip einfach ist. Es macht auch Spaß zu lesen, während das Funktionsprinzip des Befehls vorweggenommen wird.
Recommended Posts