du ist ein Befehl zum Anzeigen der Verzeichniskapazität. Wenn Sie es ohne Optionen verwenden, werden alle Verzeichniskapazitäten unter dem aktuellen Verzeichnis angezeigt. Dieses Mal werde ich die Implementierung verfolgen, um zu sehen, wie die Funktion realisiert wird.
Als Verhalten wäre es schön, wenn es eine Funktion gäbe, um das Verzeichnis zu verfolgen und die Dateigröße darin zu addieren. Dafür sind wahrscheinlich die folgenden Funktionen erforderlich.
Schauen wir uns die Implementierung an und konzentrieren uns darauf, wie diese Funktionen realisiert werden.
Dieses Mal werden wir uns den Quellcode von du.c ansehen, der in GNU coreutils enthalten ist.
Die Hauptfunktion ruft du_files ()
auf.
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 ()
.
(3) Rufen Sie "process_file ()" auf und kehren Sie zu (2) zurück.
xfts_open()
"Xfts_open ()" in (1) ist ein Wrapper für "fts_open ()" und intern wird "fts_open ()" aufgerufen. Das an xfts_open () übergebene Argument ist der Dateiname. Dieser Dateiname wird durch das Befehlszeilenargument angegeben. Wenn kein Argument vorhanden ist, wird das aktuelle Verzeichnis übergeben.
Die von xfts_open () erhaltene FTS-Struktur ist ein Handle der Dateihierarchie. Das Feld verfügt über eine FTSENT-Struktur, die Informationen zur Datei darstellt, sowie über die aktuelle Position und untergeordnete FTSENT-Strukturen. Jedes Mal, wenn Sie in (2) fts_read ()
aufrufen, ändern sie sich und folgen der Dateihierarchie (siehe unten).
fts_read() In (2) "fts_read ()" wird die FTSENT-Struktur an der aktuellen Position aus der FTS-Struktur erhalten. Die FTSENT-Struktur enthält die folgenden Felder (fts).
python
typedef struct _ftsent {
unsigned short fts_info; /*Flags für FTSENT-Strukturen*/
char *fts_accpath; /*Zugriffspfad*/
char *fts_path; /*Wurzelpfad*/
short fts_pathlen; /* fts_Pfadlänge*/
char *fts_name; /*Dateiname*/
short fts_namelen; /* fts_Länge des Namens*/
short fts_level; /*Tiefe(-1 〜 N) */
int fts_errno; /*Datei Fehlernummer*/
long fts_number; /*Lokale Nummer*/
void *fts_pointer; /*Lokale Adressnummer*/
struct ftsent *fts_parent; /*Übergeordnetes Verzeichnis*/
struct ftsent *fts_link; /*Die folgende Dateistruktur*/
struct ftsent *fts_cycle; /*Zirkulierende Struktur*/
struct stat *fts_statp; /* stat(2)Information*/
} FTSENT;
Die Dateigröße ist in fts_stap
(stat).
python
struct stat {
dev_t st_dev; /*ID des Geräts, auf dem sich die Datei befindet*/
ino_t st_ino; /*Inode-Nummer*/
mode_t st_mode; /*Zugangsschutz*/
nlink_t st_nlink; /*Anzahl der Hardlinks*/
uid_t st_uid; /*Benutzer-ID des Besitzers*/
gid_t st_gid; /*Gruppen-ID des Besitzers*/
dev_t st_rdev; /*Geräte ID(Für spezielle Dateien) */
off_t st_size; /*Gesamte Größe(Byteeinheit) */
blksize_t st_blksize; /*Dateisystem I./In O.
Block Größe*/
blkcnt_t st_blocks; /*Anzahl der zugewiesenen 512B-Blöcke*/
};
Daher kann die Dateigröße erhalten werden, indem die Statistikstruktur aus der FTSENT-Struktur verfolgt wird.
Nun wurde die FTSENT-Struktur durch fts_read ()
in (2) erhalten. Da fts_read ()
automatisch der Dateihierarchie folgt, scheint es, dass der Befehl du implementiert werden kann, indem fts_read ()
wiederholt aufgerufen und die Dateigröße summiert wird. Der Vorgang der Summierung der Dateigröße erfolgt über "process_file ()" in (3).
Bevor wir uns nun mit der Erläuterung von (3) befassen, sehen wir uns an, wie die Dateihierarchie mit fts_read ()
verfolgt wird. Überprüfen Sie den Vorgang mit dem folgenden Code (Lesen Sie die ls von FreeBSD Lassen Sie uns ls mit fts (3) ~ machen).
python
#include <stdio.h>
#include <stdlib.h>
#include <fts.h>
int main (int argc, char *argv[])
{
FTS *ftsp;
FTSENT *p;
static char dot[] = ".";
static char *dotav[] = {dot, NULL};
if (argc == 1)
argv = dotav;
else
argv++;
ftsp = fts_open(argv, 0, NULL);
while((p = fts_read(ftsp)) != NULL) {
printf("%s\n", p->fts_path);
}
fts_close(ftsp);
exit(EXIT_SUCCESS);
}
Dieser Code ist eine Implementierung des Befehls ls mit der Funktion fts. Alle Dateien und Verzeichnisse unter dem Verzeichnis werden angezeigt. Das fts_read ()
in der while
-Anweisung folgt der Dateihierarchie, und das p-> fts_path
zeigt den Dateinamen an.
Das Ausführungsergebnis ist wie folgt.
$ ./ls
.
./dir1
./dir1/file3
./dir1/file4
./dir1/dir2
./dir1/dir2/file5
./dir1/dir2
./dir1
./ls.c
./ls
./file2
./file1
.
Die Anzeigereihenfolge ist wie folgt.
Sie können sehen, dass die Tiefe priorisiert ist, die Datei einmal durchlaufen wird und das Verzeichnis zweimal durchlaufen wird.
Nächstes Mal wird der Prozess von process_file () in (3) angezeigt.
Recommended Posts