d_type
ist eine Geschwindigkeitsoptimierung, um auf lstat(2)
zu sparen Anrufe, wenn es unterstützt wird.
Als readdir
(3) Manpage weist darauf hin, dass nicht alle Dateisysteme echte Informationen in d_type
zurückgeben Feld (normalerweise, weil es eine zusätzliche Festplattensuche erfordern würde, um den Inode zu lesen, wie es bei XFS der Fall ist, wenn Sie mkfs.xfs -n ftype=1
nicht verwenden (impliziert durch -m crc=1
was noch nicht der Standard ist). Dateisysteme, die immer DT_UNKNOWN
setzen sind im wirklichen Leben üblich und können nicht ignoriert werden. XFS ist nicht das einzige Beispiel.
Sie benötigen immer Code, der auf die Verwendung von lstat
zurückgreift (2) wenn d_type==DT_UNKNOWN
, wenn der Dateiname allein nicht ausreicht, um zu entscheiden, ob er uninteressant ist. (Dies ist bei einigen Anrufern der Fall, wie z. B. find -name
oder expandierende Globs wie *.c
, weshalb readdir
verursacht nicht den Aufwand, es auszufüllen, wenn es einen zusätzlichen Lesevorgang auf der Festplatte erfordern würde.)
Der Linux-getdents(2)
Manpage enthält ein Beispielprogramm, das das tut, was Sie versuchen, einschließlich eines verketteten ternären Operatorblocks zum Decodieren von d_type
Feld in Textzeichenfolgen. (Wie die anderen Antworten zeigen, druckt Ihr Fehler es als Zeichen aus, anstatt es mit DT_REG
zu vergleichen , DT_DIR
usw.)
Wie auch immer, die anderen Antworten deckten hauptsächlich Dinge ab, übersahen jedoch das kritische Detail, dass Sie ein Fallback BENÖTIGEN für den Fall d_type == DT_UNKNOWN
(0 unter Linux. d_type
wird in einem ehemaligen Füllbyte gespeichert, bis Linux 2.6.4).
Um portierbar zu sein, muss Ihr Code diesen struct dirent
überprüfen HAT sogar einen d_type
Feld, wenn Sie es verwenden, oder Ihr Code wird nicht einmal kompiliert außerhalb von GNU- und BSD-Systemen. (siehe readdir(3)
)
Ich habe ein Beispiel für das Finden von Verzeichnissen mit readdir geschrieben , mit d_type
mit einem Fallback auf stat
wenn d_type zur Kompilierzeit nicht verfügbar ist, wenn es DT_UNKNOWN ist und für symbolische Links.
Die d_type
in der Rückgabestruktur gibt eine Zahl für den Typ an. Sie können das nicht direkt drucken, da die verwendeten Werte nicht druckbar sind, wenn sie als ASCII interpretiert werden (zum Beispiel sind sie 4 für Verzeichnisse und 8 für Dateien.).
Sie können sie entweder als Zahlen wie folgt drucken:
printf("%d ", dent->d_type)
Oder vergleichen Sie sie mit den Konstanten wie DT_DIR
und konstruieren Sie daraus eine aussagekräftige Ausgabe, wie einen char-Typ:
if(dent->type == DT_DIR) type = 'd'
Drucken Sie d_type
als Integer wie folgt:
printf("%d ", dent->d_type);
und Sie sehen aussagekräftige Werte.