Um erst einmal ein Gespür dafür zu bekommen, wie Dateien ihre Inhalte speichern und auch wieder abrufen können, muss man sich in erster Linie mit dem Gedanken anfreunden, dass Dateien nichts weiter sind als eine große Anzahl von Blöcken.
Bekanntlich bestehen Festplatten aus Sektoren – diese Sektoren werden zusammengefasst mittels des Clusterfaktors – und anhand dieses Gebildes entstehen die Blöcke. Um das doch noch etwas zu verdeutlichen, ein kurzes Beispiel.
Sektoren besitzen eine Größe von 512 Byte und ein Block soll die Größe von 4096 Byte besitzen – das bedeutet man benötigt acht Sektoren um einen Block zusammenstellen zu können. Dem entsprechend würde die Rechnung wie folgt aussehen.
Größe der Sektoren * dem Clusterfaktor = Größe eines Blocks
Das bedeutet für unser Beispiel: 512 Byte * 8 = 4096 Byte (oder auch 4 KB).
Zusammenhängende Belegung
Die einfachste Belegung ist die der zusammenhängenden Belegung, sprich die Datenblöcke werden nacheinander auf dem Speicher angeordnet – der Vorteil dabei ist, dass nicht viel über die Datenblöcke bekannt sein muss, lediglich zwei Faktoren würden für den Zugriff ausreichen, nämlich wo beginnt der erste Datenblock bzw. wie schaut dessen Adresse aus und wie viele Blöcke gehören im Anschluss zu der Datei. Das bedeutet es wird der erste Datenblock gelesen, da man weiß wie viele noch folgen ist auch somit der letzte Datenblock bekannt. Des Weiteren ist die Leseleistung, also die Geschwindigkeit in der die Blöcke gelesen werden, sehr gut. Das liegt einfach daran, dass man mit einer einzigen Operation den Zugriff auf alle Datenblöcke hat und diese somit recht schnell gelesen werden können.
Das Resultat dabei ist, dass die Daten mit der vollen Bandbreite, je nach Leistung der Festplatte, übertragen / ausgelesen werden können. Diese Art von Implementierung ist recht einfach und besitzt eine hohe Performance.
Doch so schön auch die Vorteile seien mögen, liegen die Nachteile auf der Hand – sobald Inhalte bzw. Dateien gelöscht werden, entstehen Lücken im Speicher, also eine Vielzahl von freien Blöcken, die nicht zwangsläufig wieder von anderen Dateien gefüllt werden können, da neue Dateien auch größer sein können, als die vorhandene Lücke und somit einen anderen Platz auf der Platte finden müssen – das sorgt zwangsläufig dafür, dass die Platte im Laufe der Zeit stark fragmentiert wird. Denkt man nun an die Möglichkeit diese Lücken durch „Defragmentierung“ zu verdichten, so muss man sich im Hinterkopf behalten, dass dies eine Verschiebung von millionen Blöcken zur Folge haben würde – diese Verschiebung ist nicht nur Zeit- sondern auch Kostenintensiv.
Sofern die Festplatte noch leer ist, würde die Fragmentierung keine Probleme bereiten, aber irgendwann ist eine Festplatte auch voll – und man steht vor der Entscheidung die Blöcke zu verdichten oder eben die freien Blöcke wiederzuverwenden. Aber selbst das wiederverwenden von freien Blöcken ist eine Sache welche recht aufwendig sein kann, da eine Liste von „freien Blöcken“ bzw. „Lücken“ geführt werden müsste und es setzt voraus, dass bei der Erstellung einer Datei, vorab die endgültige Größe bekannt ist – das würde heißen, dass Dateien ggf. nicht in der Lage sind zu wachsen, denn sobald die Lücke gänzlich gefüllt ist, bereits die nächsten Blöcke einer anderen Datei angrenzen würden.
Belegung durch verkettete Listen
Ein weiterer Ansatz wäre, die Belegung durch verkettete Liste, damit ist schon einmal die Chance gegeben, dass Dateien nun in der Lage sind zu wachsen – sofern die Festplatte nicht bis zum Anschlag mit Dateien und etwaigen Informationen gefüllt ist.
Das Prinzip ist recht einfach, dass erste Wort eines Blocks wird als Zeiger auf den nächsten Block genutzt. Somit verweist Block 0 auf Block 8 und Block 8 kann wiederum auf einen anderen Block, beispielsweise auf den Block 3 verweisen, obwohl dieser eigentlich vor dem Block 8 liegt.
Der Vorteil dieser Art von verketteter Liste ist, dass kein Speicher durch Fragmentierung verloren geht, sondern jegliche entstehende Lücke gefüllt werden kann. Für den Verzeichniseintrag reicht es dabei sogar aus, nur den ersten Block zu kennen – da jeder Block selbst auf den nächsten referenziert.
Das Problem welches dabei entsteht ist, dass der Zeiger innerhalb des Blocks Speicherplatz belegt und Programme bzw. Anwendungen arbeiten häufig mit „zweiter Potenzen“ wie Beispielsweise 2 ^ 12 (also 2 hoch 12), was eine Blockgröße von 4096 Byte bedeutet. Wenn der Zeiger nun selbst einen Teil einnimmt zum Beispiel 144 Byte – würde das bedeuten, dass diese zweiter Potenz nicht mehr gegeben ist. Des Weiteren werden durch die Verkettung die Lesezugriffe langsamer, weil die einzelnen Blöcke verknüpft werden müssen und somit natürlich mehr Operationen notwendig sind.
Belegung von verketteten Listen mit einer Tabelle im Arbeitsspeicher
Wie man bereits bei der Belegung durch verkettete Listen sehen konnte, geht dadurch Speicherplatz verloren – dazu gibt es die Möglichkeit dies mithilfe des Arbeitsspeichers zu lösen.
Das Problem wird im Endeffekt dadurch gelöst, dass sich der Zeiger für jeden Block im Arbeitsspeicher befindet, somit referenzieren nicht die Blöcke aufeinander, sonder der Zeiger im Arbeitsspeicher – dazu dient eine Tabelle im Arbeitsspeicher, welche Fat Allocation Tabelle genannt wird und den meisten Benutzern, wohl unter der Kurzform „FAT“ bekannt ist.
Das Ende einer Kette wird durch eine spezielle Markierung (-1) im Arbeitsspeicher bzw. in der Tabelle dargestellt. Somit steht der komplette Datenblock für Daten zur Verfügung. Der Nachteil ist, dass sich die Tabelle dauerhaft im Arbeitsspeicher befinden muss – das bedeutet, wenn ein Block 4 KB groß ist, und man 1.000.000 Blöcke hat, sind faktisch 3.9 GB vom vorhandenen Arbeitsspeicher belegt.
Das bedeutet, der genutzte Arbeitsspeicher steht damit für weitere Anwendungen nicht zur Verfügung.
Inodes
Inodes besitzen den großen Vorteil, dass sich die dazugehörige Datenstruktur nur im Hauptspeicher befinden muss, wenn eine Datei geöffnet ist. Das heißt, der Arbeitsspeicher wird nur dann belegt, wenn es auch notwendig ist. Im Vergleich zu verketteten Listen mit einem Zeiger im Arbeitsspeicher ist der Speicher, welcher belegt wird, eher gering.
Bei einer Inode wird jeder Datei genau eine Datenstruktur zugewiesen – daher nennt man Inodes im Fachjargon auch Indexknoten. Diese Datenstruktur enthält sämtliche Informationen einer Datei, wie zum Beispiel deren Attribute oder auch welche Blöcke belegt werden, ob diese Blöcke direkt, einfach indirekt oder doppelt indirekt „verschachtelt“ sind.
Also sofern eine Inode gegeben ist, ist man in der Lage sämtliche Datenblöcke die zu der Datei gehören aufzuspüren. Ein weiterer großer Vorteil der Inode ist, dass die nicht abhängig der Plattengröße bzw. der Blockgröße ist, wie es bei verketteten Listen üblich ist.
Fazit zur Speicherbelegung
Die Speicherung von Dateien als zusammenhängende Bytefolge, hat das Problem, dass Blöcke wahrscheinlich verschoben werden müssen, wenn eine Datei wächst. Genau aus diesem Grund greifen die heutigen Dateisysteme auf andere Verfahren zurück. Diese Verfahren spalten die Dateien in Blöcke bzw. Datenblöcke mit einer festen Größe und setzen nicht voraus, dass diese in irgendeiner Art und Weise benachbart sein müssen.
Dokument herunterladen:
Speicherbelegung Dateisysteme (466.98KB | .pdf)
Speicherbelegung Dateisysteme (33.5KB | .doc)
Speicherbelegung Dateisysteme (14.48KB | .docx)


Danke für den Artikel