d_type
je optimalizace rychlosti pro úsporu lstat(2)
volání, pokud je to podporováno.
Jako readdir
(3) manuálová stránka zdůrazňuje, že ne všechny souborové systémy vracejí skutečné informace v d_type
pole (obvykle proto, že čtení inodu by vyžadovalo další hledání disku, jako je tomu v případě XFS, pokud jste nepoužili mkfs.xfs -n ftype=1
(předpokládá se -m crc=1
což ještě není výchozí nastavení). Souborové systémy, které vždy nastavují DT_UNKNOWN
jsou v reálném životě běžné a nelze je ignorovat. XFS není jediným příkladem.
Vždy potřebujete kód, který se vrátí k použití lstat
(2) pokud d_type==DT_UNKNOWN
, pokud samotný název souboru nestačí k rozhodnutí, že je nezajímavý. (To je případ některých volajících, například find -name
nebo rozšiřující globusy jako *.c
, proto readdir
nezahrnuje režii jeho vyplňování, pokud by to vyžadovalo další čtení disku.)
Linux getdents(2)
manuálová stránka obsahuje ukázkový program, který dělá to, o co se pokoušíte, včetně bloku řetězeného ternárního operátora pro dekódování d_type
pole do textových řetězců. (Jak zdůrazňují ostatní odpovědi, vaše chyba je vytisknout jej jako znak, spíše než jej porovnat s DT_REG
, DT_DIR
, atd.)
Každopádně ostatní odpovědi většinou pokrývaly věci, ale postrádaly kritický detail, že POTŘEBUJETE záložní řešení pro případ, kdy d_type == DT_UNKNOWN
(0 v systému Linux. d_type
je až do Linuxu 2.6.4 uloženo v tom, co bývalo výplňovým bytem).
Aby byl váš kód přenosný, musí zaškrtnout struct dirent
dokonce MÁ d_type
pole, pokud jej použijete, jinak se váš kód nebude ani zkompilovat mimo systémy GNU a BSD. (viz readdir(3)
)
Napsal jsem příklad hledání adresářů pomocí readdir pomocí d_type
s přechodem na stat
když d_type není k dispozici v době kompilace, když je DT_UNKNOWN a pro symbolické odkazy.
d_type
ve struktuře return udává číslo pro typ. Nemůžete to vytisknout přímo, protože použité hodnoty nelze vytisknout, když jsou interpretovány jako ASCII (například jsou 4 pro adresáře a 8 pro soubory).
Můžete je vytisknout jako čísla takto:
printf("%d ", dent->d_type)
Nebo je porovnejte s konstantami jako DT_DIR
a vytvořit z toho nějaký smysluplný výstup, jako je typ znaku:
if(dent->type == DT_DIR) type = 'd'
Vytiskněte d_type
jako celé číslo takto:
printf("%d ", dent->d_type);
a uvidíte smysluplné hodnoty.