Myös inodet säilytetään levyllä, eli jos halutaan lukea tietyn tiedoston sisältö, on tiedostojärjestelmän ensin etsittävä levyltä tiedostoa vastaava inode ja katsottava inoden sisältä missä päin levyä tiedoston data on talletettuna.
Tiedostojen nimi ei ole talletettu inodeen. Tiedoston nimi löytyy ainoastaan hakemistosta. Hakemistot ovat tiedostoja, jotka sisältävät tiedostojen nimiä ja viitteitä nimiä vastaaviin inodeihin.
Seuraava kuva havainnollistaa hakemiston ja inoden suhdetta.

Hakemisto siis sisältää sen sisältämien tiedostojen (ja hakemistojen) nimet sekä linkin niitä vastaaviin inodeihin. Tiedostojen attribuutit löytyvät inodesta, samoin kun linkit niihin levylohkoihin jotka tallettavat tiedoston datan.
SYNOPSIS
#include < sys/types.h>
#include < sys/stat.h>
#include < unistd.h>
int stat(const char *file_name, struct stat *buf);
int fstat(int filedes, struct stat *buf);
DESCRIPTION
These functions return information about the specified file. You do
not need any access rights to the file to get this information but you
need search rights to all directories named in the path leading to the
file.
stat stats the file pointed to by file_name and fills in buf.
fstat is identical to stat, only the open file pointed to by filedes
(as returned by open(2)) is stat-ed in place of file_name.
They all return a stat structure, which contains the following fields:
struct stat {
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device type (if inode device) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last change */
};
stat ja fstat -operaatioiden avulla siis saadaan struct stat -tyyppinen tietue,
jonka kenttinä löytyy tietoa tiedoston ominaisuuksista. Komennot eroavat
toisistaan sen suhteen, että statin ensimmäisenä parametrina on tiedoston
nimi ja fstatissa avoimen (openilla avatun) tiedoston tiedostokuvaaja.Tiedoston nimi Unixeissa on joko absoluuttinen tai suhteellinen. Absoluuttinen polkunimi alkaa /-merkillä. Esim. tämän html-tiedoston absoluuttinen polkunimi on /home/luuma/public_html/kj/vko10/index.html. Suhteellinen polkunimi taas kertoo tiedoston nimen suhteessa työhakemistoon. Jos työhakemistona olisi /home/luuma/public_html/kj, viitataan tähän html-tiedostoon suhteellisella nimellä vko10/index.html.
Eli jos käytetään tiedstoista suhteellisia nimiä, on työhakemiston oltava oikea. Kun ohjelma käynnistetään komentotulkista, tulee ohjelman työhakemistoksi se hakemisto missä komentotulkki oli ohjelman käynnistyshetkellä. Ohjelma voi vaihtaa työhakemistoa komennolla chdir, man-sivulta:
#include < unistd.h>
int chdir(const char *path);
DESCRIPTION
chdir changes the current directory to that specified in path.
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is
set appropriately.
Työhakemiston saa selville komennolla getcwd, man-sivulta:
#include < unistd.h>
char *getcwd(char *buf, size_t size);
DESCRIPTION
The getcwd() function copies an absolute pathname of the current work-
ing directory to the array pointed to by buf, which is of length size.
If the current absolute path name would require a buffer longer than
size elements, NULL is returned, and errno is set to ERANGE; an appli-
cation should check for this error, and allocate a larger buffer if
necessary.
If buf is NULL, the behaviour of getcwd() is undefined.
RETURN VALUE
NULL on failure with errno set accordingly, and buf on success. The
contents of the array pointed to by buf is undefined on error.
Esimerkkinä ohjelma 10-1.c, joka
ensin tulostaa ohjelmatiedostonsa koon tavuina. Tämän jälkeen ohjelma
tulostaa työhakemistonsa, siirtyy hakemistotasolla yhden tason alaspäin
(eli sama kuin cd ..) ja tulostaa jälleen oman työhakemistonsa.
Koodi seuraavassa:
#define SIZE 1024
int main(int argc, char *argv[]){
struct stat attrib;
char buf[SIZE];
// pyydetään ohjelmatiedoston attribuutit
stat(argv[0], &attrib);
// tulostetaan koko
printf("tiedoston %s koko %d tavua\n", argv[0], attrib.st_size);
// tulostetaan työhakemisto
getcwd(buf, SIZE);
printf("työhakemisto: %s\n", buf);
// mennään yksi taso alaspäin
chdir("..");
getcwd(buf, SIZE);
printf("ja nyt: %s\n", buf);
return 0;
}
#include < sys/types.h>
#include < dirent.h>
DIR *opendir(const char *name);
DESCRIPTION
The opendir() function opens a directory stream corresponding to the
directory name, and returns a pointer to the directory stream. The
stream is positioned at the first entry in the directory.
RETURN VALUE
The opendir() function returns a pointer to the directory stream or
NULL if an error occurred.
opendir siis palauttaa osoittimen DIR-tyyppiseen muuttujaan.Avoinna olevan hakemiston sisältö luetaan komennolla readdir. readdir palauttaa hakemistosta yhden hakemistomerkinnän (directory entry) kerrallaan.
readdirin man-sivulla (huom: sektiossa 3) sanotaan seuraavasti:
#include < sys/types.h>
#include < dirent.h>
struct dirent *readdir(DIR *dir);
DESCRIPTION
The readdir() function returns a pointer to a dirent structure repre-
senting the next directory entry in the directory stream pointed to by
dir. It returns NULL on reaching the end-of-file or if an error
occurred.
According to POSIX, the dirent structure contains a field char d_name[]
of unspecified size, with at most NAME_MAX characters preceding the
terminating null character. Use of other fields will harm the porta-
bility of your programs. POSIX 1003.1-2001 also documents the field
ino_t d_ino as an XSI extension.
The data returned by readdir() may be overwritten by subsequent calls
to readdir() for the same directory stream.
RETURN VALUE
The readdir() function returns a pointer to a dirent structure, or NULL
if an error occurs or end-of-file is reached.
readdir siis palauttaa osoittimen struct dirent -tyyppiseen tietueeseen.
Tietueella on kenttinä tiedoston nimi d_name, ja tiedoston inoden numero
d_ino.
readdirillä luetaan hakemiston sisältöä yksi merkintä kerrallaan. Hakemiston koko sisältö saadaan luetuksi kutsumalla readdiriä toistuvasti kunnes koko sisältö on luettu ja readdir palauttaa NULL:in.
Avoinna olevan hakemiston sulkeminen tapahtuu komennolla closedir, joka saa parametrikeen opendirin palauttaman DIR-osoittimen. Ohjelma 10-2.c toteuttaa suunnilleen saman kun komento ls ilman komentoriviparametreja.
int main(void){
DIR *hakemisto; // hakemistokahva
struct dirent *entry; // osoitin hakemistomerkintään
// avataan nykyhakemisto eli ".", operaatio palauttaa hakemistokahvan
hakemisto = opendir(".");
while( 1 ){
entry = readdir(hakemisto);
if ( entry == NULL ) break; // ollaan lopussa
// tulostetaan hakemistomerkinnän nimi ruudulle
printf("%s\n",entry->d_name);
}
// suljetaan hakemisto
closedir(hakemisto);
return 0;
}
Ojelma 10-3.c on hieman kehittyneempi versio edellisestä.
Ohjelma tulostaa joko parametrina annetun hakemiston sisällön tai jos
parametria ei ole, tulostetaan sen hakemiston sisältö missä ohjelma
käynnistetään.
int main(int argc, char *argv[]){
DIR *hakemisto; // hakemistokahva
struct dirent *entry; // osoitin hakemistomerkintään
struct stat attrib; // muuttuja tiedoston/hakemiston attribuuteille
char *hnimi = "."; // avattavan hakemiston nimi
// jos komentoriviparametri, sijoitetaan tämä luettavan hakemiston nimeksi
if ( argc>1 ) hnimi = argv[1];
// avataan hakemisto, operaatio palauttaa hakemistokahvan
hakemisto = opendir(hnimi);
// testataan epäonnistuiko operaatio
if ( hakemisto == NULL ) {
printf("hakemistoa %s ei olemassa\n",hnimi);
return 0;
}
// laitetaan ohjelman hakemistoksi tutkittava hakemisto
chdir(hnimi);
Nyt hakemisto on avattuna ja muuttujassa hakemisto on DIR-osoitin, jonka
kautta hakemiston sisältöä luetaan. Viimeisenä komentona edellä oli chdir,
jolla siirrytään siihen hakemistoon, minkä sisältö tulostetaan.
Tämä ei ole hakemiston selaamisen kannalta oleellista, mutta koska jatkossa
käytetään stat-komentoa ja suhteellisia polkunimiä, niin ohjelman työhakemiston
on oltava sama kun selattava hakemisto.
Perusratkaisuna jälleen while-silmukka, jossa hakemiston sisältö luetaan entry kerrallaan. Tällä kertaa toimitaan siten, että jos entry on hakemisto, tulostetaan hakemiston nimen perään /-merkki. Jos entry on normaali tiedosto, tulostetaan tiedoston koko tavuina.
Tiedoston tyyppi selviää stat-funktion avulla. Funktion palauttaman structin st_mode-kenttä sisältää pakattuna paljon tietoa, mm. tiedon siitä minkä tyyppinen tiedosto on, eli onko kyseessä hakemisto vai normaali tiedosto. stat-komennon man-sivulta selviää, että kentän arvon tutkimiseen on olemassa valmiita makroja, esim. S_ISDIR(attrib.st_mode) on tosi (eli lausekkeella arvo 1) jos kyseessä on hakemisto ja S_ISREG(attrib.st_mode) on tosi jos kyseessä normaali tiedosto.
Ohjelma tutkii tiedoston attribuuttien st_mode-kenttää ja muotoilee tämän perusteella tulostuksen oikeanlaiseksi.
while( 1 ){
entry = readdir(hakemisto);
if ( entry == NULL ) break;
// luetaan hakemistomerkinnän attribuutut muuttujaan attrib
stat(entry->d_name, &attrib);
// testataan, onko kyseessä hakemisto
if ( S_ISDIR(attrib.st_mode) ) {
// tulostetaan hakemistonimen perään kenoviiva eli /-merkki
printf("%s/\n",entry->d_name);
}
else if ( S_ISREG(attrib.st_mode) ) {
// tulostetaan tiedoston nimen lisäksi koko tavuina
printf("%-30s %10d B\n",entry->d_name, attrib.st_size);
}
}
// suljetaan hakemisto
closedir(hakemisto);
return 0;
}

inodessa on kenttä, joka kertoo kuinka monessa hakemistossa tiedosto on linkitettynä. Kenttän arvo on stat-komennon palauttaman tietueen kentässä st_nlink. Tiedosto ja inode eivät tiedä mistä hakemistoista tiedostoon viitataan.
Kova linkki luodaan komennolla link, man-sivulta:
#include < unistd.h>
int link(const char *oldpath, const char *newpath);
DESCRIPTION
link creates a new link (also known as a hard link) to an existing
file.
If newpath exists it will not be overwritten.
This new name may be used exactly as the old one for any operation;
both names refer to the same file (and so have the same permissions and
ownership) and it is impossible to tell which name was the `original'.
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is
set appropriately.
Kuten man-sivu kuvaa, linkityksen jälkeen ei enää mistään erota mikä oli
tiedoston aluperäinen nimi.Kovan linkin (kuten myös ns. symbolisen linkin josta kohta enemmän) saa poistettua komennolla unlink, man-sivulta:
#include < unistd.h>
int unlink(const char *pathname);
DESCRIPTION
unlink deletes a name from the filesystem. If that name was the last
link to a file and no processes have the file open the file is deleted
and the space it was using is made available for reuse.
If the name was the last link to a file but any processes still have
the file open the file will remain in existence until the last file
descriptor referring to it is closed.
If the name referred to a symbolic link the link is removed.
Eli komento poistaa tiedoston jos se suoritetaan tiedostolle johon on
enää yksi linkki jäljellä. Unixeissa ei ole mitään erillistä tiedoston
poistamiseen tarkoitettua käskyä, poistaminen hoidetaan aina unlink-komennolla
ja KJ pitää huolen siitä, että jos tiedosto ei ole enää missään hakemistossa,
se poistetaan.Toinen linkkityyppi on symbolinen linkki (symbolic link tai soft link), joka luodaan komennolla symlink. Erona kovaan linkkiin on se, että symbolinen linkki ei osoita suoraan inodeen vaan sisältää jonkun polkunimen. Jos on luotu symbolinen linkki, missä nimi x.c on linkitetty tiedostoon /home/luuma/koe.c, niin tiedoston x.c avaaminen saakin aikaan sen, että avataan tiedosto /home/luuma/koe.c. Symbolinen linkki on siis vain viite johonkin toiseen kohtaan hakemistohierarkiassa. Symbolisen linkin luominen ei kasvata inoden linkkikenttää.
Jaettu muistialue luotiin shm_open-komennolla, joka palautti tiedostokuvaajan luotuun muistialueeseen. Komennolle mmap annettiin sitten muistialuetta edustanut tiedostokuvaaja, ja mmap palautti osoittimen jaetulle muistialueelle.
mmap-komentoa voidaan käyttää myös tiedoston sisällön mappaamiseksi keskusmuistiin. Tämä seikka selviää myös mmap-komennon man-sivulta:
#include < sys/mman.h>
void *mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);
DESCRIPTION
The mmap function asks to map length bytes starting at offset offset
from the file (or other object) specified by the file descriptor fd
into memory, preferably at address start. This latter address is a
hint only, and is usually specified as 0. The actual place where the
object is mapped is returned by mmap, and is never 0.
Tarkastellaan ohjelmaa 10-4.c, joka mappaa tiedoston
muistiinsa ja tulostaa muistiin mapatun tiedoston sisällön lukien tiedostoa
osoittimen avulla aivan kuin kyseessä olisi keskusmuistin sisällön lukeminen.
int main(int argc, char *argv[]){
int fd;
if ( argc<2 ) return 0;
// avataan komentoriviparametrina annettu tiedosto
fd = open( argv[1], O_RDONLY );
if ( fd == -1 ){
perror("ongelma openissa");
return -1;
}
// selvitetään tiedoston koko fstat-funktiolla
struct stat st;
fstat( fd, &st );
int koko = st.st_size;
// mapataan tiedosto muistiin, osoitteeksi p
char *p;
p = (char *) mmap( 0, koko, PROT_READ, MAP_SHARED, fd, 0 );
if ( p == MAP_FAILED ){
perror("ongelma jaetun muistialueen luomisessa");
return -1;
}
// tulostetaan mapatun muistialueen sisältö
int i;
for ( i=0; i < koko; i++ ){
printf("%c", p[i] );
}
// poistetaan mappays ja suljetaan tiedosto
munmap( p, koko );
close( fd );
return 0;
}
Jos tiedosto olisi avattu ja mapattu luku- ja kirjoitusoikeuksilla,
menisivät kaikki mapatulle muistialueelle tehdyt muutokset tiedostoon.