Συστήματα αρχείων

Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr

Απαιτήσεις

Η φύλαξη δεδομένων σε αρχεία ικανοποιεί τις παρακάτω απαιτήσεις:

Ονοματολογία

Ανάλογα με το λειτουργικό σύστημα υπάρχει διαφορετική προσέγγιση στο διαχωρισμό πεζών και κεφαλαίων: Σε ορισμένα λειτουργικά συστήματα η επέκταση του αρχείου (filename extension) έχει ειδική σημασία. Αυτή μπορεί να υποστηρίζεται μέσω ενός γενικού αντικειμενοστρεφούς σχεδιασμού του λειτουργικού συστήματος (π.χ. Windows NT) ή λόγω παραδοχών που γίνονται από τις εφαρμογές του (π.χ. MS-DOS, Unix, VMS). Για παράδειγμα στο Windows-NT ορισμένοι τύποι επέκτασης είναι οι παρακάτω:
.exeΕκτελέσιμο αρχείο
.txtΑρχείο κειμένου
.batΕκτελέσιμο αρχείο εντολών του φλοιού
.bmpΑρχείο χαρτογραφικής εικόνας
.htmΑρχείο με κείμενο HTML (Internet)
.hlpΑρχείο με δεδομένα βοήθειας
.docΑρχείο της εφαρμογής Microsoft Word
.xlsΑρχείο της εφαρμογής Microsoft Excel
.cΑρχείο πηγαίου κώδικα C
.pasΑρχείο πηγαίου κώδικα Pascal
.forΑρχείο πηγαίου κώδικα Fortran
.basΑρχείο πηγαίου κώδικα Basic
.objΜεταγλωττισμένος κώδικας
.libΒιβλιοθήκη μεταγλωττισμένου κώδικα
.dllΔυναμική βιβλιοθήκη

Δομή, τύποι και προσπέλαση αρχείων

Τύποι

Πολλά λειτουργικά συστήματα διακρίνουν ειδικούς τύπους αρχείων:

Δομή

Το λειτουργικό σύστημα μπορεί ακόμα να υποστηρίζει ορισμένη δομή αρχείων: Σε λειτουργικά συστήματα με αδόμητα αρχεία το περιεχόμενο των αρχείων ορίζεται με σύμβαση. Διακρίνονται αρχεία κειμένου (ASCII) καθώς και δυαδικά αρχεία. Το περιεχόμενο των δυαδικών αρχείων προσδιορίζεται συνήθως από το επίθεμά τους ή/και τη χρήση ενός μαγικού αριθμού (magic number).

Προσπέλαση

Σε παλαιότερα λειτουργικά συστήματα υπήρχε η διάκριση μεταξύ αρχείων σειριακής προσπέλασης (sequential access) και αρχείων τυχαίας προσπέλασης (random access).

Ιδιοχαρακτηριστικά

Στα περισσότερα λειτουργικά συστήματα κάθε αρχείο συσχετίζεται με πρόσθετες πληροφορίες, που καλούνται ιδιοχαρακτηριστικά του αρχείου (file attributes). Αυτές μπορεί να είναι:

Κλήσεις ΛΣ για χρήση αρχείων

Η πρόσβαση στα αρχεία γίνεται μέσω κλήσεων στο λειτουργικό σύστημα. Οι σημαντικότερες από αυτές είναι:
create
Δημιουργία ενός νέου αρχείου
open
Αρχή της πρόσβασης στο αρχείο
read
Ανάγνωση από το αρχείο
write
Εγγραφή στο αρχείο
seek
Μετακίνηση του δείκτη στο αρχείο
close
Τέλος της πρόσβαση στο αρχείο
Η κλήσεις open και create επιστρέφουν κατά κανόνα έναν μικρό ακέραιο τον περιγραφέα του αρχείου (file descriptor) ο οποίος χρησιμοποιείται στη συνέχεια για κάθε άλλη κλήση που έχει σχέση με το συγκεκριμένο αρχείο. Με τον τρόπο αυτό απλουστεύεται η πρόσβαση στο αρχείο μέσω του ονόματός του.

Για παράδειγμα η παρακάτω συνάρτηση αντιγράφει ένα αρχείο σε ένα άλλο (Unix):

/*
 * Copy file specified by path1 to path2
 * Return 0 on success -1 on error
 * (dds)
 */
int
copyfile(char *path1, char *path2)
{
	char	buf[512];		/* Copy buffer */
	int	ifd, ofd;		/* File descriptors */
	int	nrbytes;		/* Bytes read */
	int	nwbytes;		/* Bytes written */
	struct	stat sbuf;		/* Attribute buffer */

	/* Get attributes of source file */
	if (stat(path1, &sbuf) == -1)
		return (-1);

	/* Open source file */
	if ((ifd = open(path1, O_RDONLY)) < 0)
		return (-1);

	/* Create destination file */
	if ((ofd = creat(path2, sbuf.st_mode & 0777)) < 0) {
		close(ifd);
		return (-1);
	}

	/* Copy source to destination in chunks */
	while ((nrbytes = read(ifd, buf, sizeof(buf))) > 0) {
		if ((nwbytes = write(ofd, buf, nrbytes)) != nrbytes) {
			nrbytes = -1;
			break;
		}
	}

	/* Close source file */
	if (close(ifd) < 0) {
		close(ofd);
		return (-1);
	}

	/* Close destination file */
	if (close(ofd) < 0) {
		return (-1);
	}

	/* Success! */
	return (0);
}

Αρχεία που απεικονίζονται στη μνήμη

Η πρόσβαση σε αρχεία μπορεί να γίνει και χωρίς τη χρήση read/write/seek με την απευθείας απεικόνισή τους στη μνήμη. Ο τρόπος προσφέρει διαφάνεια στην πρόσβαση και καλύτερες επιδόσεις, ειδικά όταν συνδυάζεται με κατάτμηση για την 1-1 απεικόνιση διευθύνσεων του αρχείου με διευθύνσεις μνήμης και σελιδοποίηση για την ανίχνευση κάθε ανάγνωσης και εγγραφής σχετικής με το αρχείο. Η πρόσβαση στα αρχεία με τον τρόπο αυτό γίνεται μέσω κλήσεων στο λειτουργικό σύστημα και στη συνέχεια χρήσης της αντίστοιχης μνήμης (μέσω δεικτών ή πινάκων). Οι σχετικές κλήσεις είναι:
map
Σύνδεση μιας περιοχής της μνήμης με ένα αρχείο
unmap
Τερματισμός της αντίστοιχης σύνδεσης
Στο Unix οι αντίστοιχες κλήσεις είναι οι:
void *mmap(void  *start,  size_t length, int prot , int flags, 
	   int fd, off_t offset);

int munmap(void *start, size_t length);           

Υλοποίηση αρχείων

Η υλοποίηση του συστήματος των αρχείων μπορεί να γίνει με διάφορους τρόπους κατανομής του χώρου του δίσκου. Κάθε τρόπος πρέπει να επιτρέπει σειριακή και τυχαία πρόσβαση στο αρχείο. Μερικοί τρόποι είναι οι παρακάτω:

Ιεραρχικά συστήματα καταλόγων

Κλήσεις ΛΣ για χρήση καταλόγων

Η πρόσβαση στους καταλόγους γίνεται μέσω κλήσεων στο λειτουργικό σύστημα. Οι σημαντικότερες από αυτές είναι:
delete
Διαγραφή ενός αρχείου από έναν κατάλογο
get attributes
Ανάγνωση των ιδιοχαρακτηριστικών ενός αρχείου
set attributes
Αλλαγή των ιδιοχαρακτηριστικών ενός αρχείου
rename
Μετονομασία ενός αρχείου (ή καταλόγου)
mkdir
Δημιουργία ενός καταλόγου
rmdir
Διαγραφή ενός καταλόγου
opendir
Αρχή πρόσβασης στα στοιχεία ενός καταλόγου
readdir
Ανάγνωση στοιχείων από έναν κατάλογο
closedir
Τέλος της πρόσβασης στον κατάλογο
link
Σύνδεση δύο αρχείων μεταξύ τους
symlink
Συμβολική σύνδεση δύο αρχείων μεταξύ τους

Υλοποίηση καταλόγων

Οι κατάλογοι τυπικά υλοποιούνται ως πίνακες που περιέχουν:

Διαχείριση χώρου

Αξιοπιστία συστημάτων αρχείων

Το λειτουργικό σύστημα ή εξωτερικά προγράμματα μεριμνούν για

Επίδοση συστημάτων αρχείων

Βιβλιογραφία

Εργασία στο εργαστήριο

Διαβάστε τη σελίδα του εγχειριδίου του Unix για τις κλήσεις open και stat. Προσέξτε τις παραμέτρους που λαμβάνουν και τον αριθμό των πιθανών λαθών που ελέγχουν.
kerkis:/proc$ man  2 open | head -20



OPEN(2)                    System calls                   OPEN(2)


NAME
       open, creat - open and possibly create a file or device

SYNOPSIS
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);
       int creat(const char *pathname, mode_t mode);

DESCRIPTION
       open  attempts to open a file and return a file descriptor              
...

Μετρήστε το χρόνο που χρειάζεται η αντιγραφή ενός αρχείου στο ψευδοαρχείο /dev/null. Εκτελέστε την εντολή ξανά και συγκρίνετε τους χρόνους. Παρατηρήστε το αποτέλεσμα της κρυφής μνήμης.

athena:~> cd /usr/man/man1
athena:/usr/man/man1>     
athena:/usr/man/man1> time cat pgp.1 >/dev/null
0.000u 0.030s 0:00.20 15.0% 0+0k 0+0io 16pf+0w
athena:/usr/man/man1> time cat pgp.1 > /dev/null
0.000u 0.030s 0:00.02 150.0% 0+0k 0+0io 16pf+0w
athena:/usr/man/man1>