Defragmentieren von Dateien

Wenn eine Datei auf einen Datenträger geschrieben wird, kann die Datei manchmal nicht in zusammenhängenden Clustern geschrieben werden. Nicht zusammenhängende Cluster verlangsamen den Prozess des Lesens und Schreibens einer Datei. Je weiter sich die nicht zusammenhängenden Cluster auf einem Datenträger voneinander unterscheiden, desto schlimmer ist das Problem, da die Zeit zum Verschieben des Lese-/Schreibkopfs einer Festplatte benötigt wird. Eine Datei mit nicht zusammenhängenden Clustern ist fragmentiert. Um Dateien für den schnellen Zugriff zu optimieren, kann ein Volume defragmentiert werden.

Die Defragmentierung ist der Prozess des Verschiebens von Teilen von Dateien auf einem Datenträger, um Dateien zu defragmentieren, d. h. der Prozess des Verschiebens von Dateiclustern auf einem Datenträger, um sie zusammenhängend zu machen. Weitere Informationen finden Sie in den folgenden Abschnitten:

Defragmentieren einer Datei

In einem einfachen Single-Tasking-Betriebssystem ist die Defragmentierungssoftware die einzige Aufgabe, und es gibt keine anderen Prozesse zum Lesen oder Schreiben auf den Datenträger. In einem Multitasking-Betriebssystem können jedoch einige Prozesse von einer Festplatte lesen und auf eine Festplatte schreiben, während ein anderer Prozess diese Festplatte defragmentiert. Der Trick besteht darin, Schreibvorgänge in eine Datei zu vermeiden, die defragmentiert wird, ohne den Schreibvorgang sehr lange zu beenden. Dieses Problem zu lösen ist nicht trivial, aber möglich.

Um die Defragmentierung ohne detaillierte Kenntnisse einer Dateisystemdatenträgerstruktur zu ermöglichen, wird ein Satz von drei Steuercodes bereitgestellt. Die Steuercodes bieten die folgende Funktionalität:

  • Aktivieren von Anwendungen zum Suchen nach leeren Clustern
  • Ermitteln des Speicherorts von Dateiclustern
  • Verschieben von Clustern auf einem Datenträger

Die Steuerungscodes behandeln auch transparent das Problem, dass andere Prozesse während Verschiebungen aus Dateien lesen und in diese schreiben können.

Diese Vorgänge können ausgeführt werden, ohne die Ausführung anderer Prozesse zu verhindern. Die anderen Prozesse weisen jedoch langsamere Antwortzeiten auf, während ein Datenträgerlaufwerk defragmentiert wird.

So defragmentieren Sie eine Datei

  1. Verwenden Sie den FSCTL_GET_VOLUME_BITMAP-Steuerelementcode, um einen Ort auf dem Volume zu finden, der groß genug ist, um eine gesamte Datei zu akzeptieren.

    Hinweis

    Verschieben Sie bei Bedarf andere Dateien, um einen Ort zu erstellen, der groß genug ist. Im Idealfall gibt es nach dem ersten Bereich der Datei genügend nicht zugeordnete Cluster, die Sie nach dem ersten Bereich in den Bereich verschieben können.

     

  2. Verwenden Sie den FSCTL_GET_RETRIEVAL_POINTERS-Steuerelementcode, um eine Zuordnung des aktuellen Layouts der Datei auf dem Datenträger abzurufen.

  3. Führen Sie die RETRIEVAL_POINTERS_BUFFER Struktur aus , die von FSCTL_GET_RETRIEVAL_POINTERS zurückgegeben wird.

  4. Verwenden Sie den FSCTL_MOVE_FILE-Steuerelementcode, um jeden Cluster beim Durchlaufen der Struktur zu verschieben.

    Hinweis

    Möglicherweise müssen Sie entweder die Bitmap oder die Abrufstruktur oder beides zu verschiedenen Zeiten erneuern, wenn andere Prozesse auf den Datenträger schreiben.

     

Zwei der Vorgänge, die beim Defragmentierungsprozess verwendet werden, erfordern ein Handle für ein Volume. Nur Administratoren können ein Handle für ein Volume abrufen, sodass nur Administratoren ein Volume defragmentieren können. Eine Anwendung sollte die Rechte eines Benutzers überprüfen, der versucht, Defragmentierungssoftware auszuführen, und es sollte einem Benutzer nicht erlauben, ein Volume zu defragmentieren, wenn der Benutzer nicht über die entsprechenden Rechte verfügt.

Wenn Sie CreateFile verwenden, um ein Verzeichnis während der Defragmentierung eines FAT- oder FAT32-Dateisystemvolumes zu öffnen, geben Sie den Wert GENERIC_READ Zugriffsmaske an. Geben Sie nicht den Wert MAXIMUM_ALLOWED Zugriffsmaske an. Der Zugriff auf das Verzeichnis wird verweigert, wenn dies geschieht.

Versuchen Sie nicht, zugeordnete Cluster in einem NTFS-Dateisystem zu verschieben, das über die gerundete Clusterdateigröße hinausgeht, da das Ergebnis ein Fehler ist.

Neu analysieren von Punkten, Bitmaps und Attributlisten in NTFS-Dateisystemvolumes können defragmentiert, zum Lesen und synchronisieren geöffnet und mithilfe der Syntax file:name:type benannt werden. Beispiel : dirname:$i 30:$INDEX_ALLOCATION, mrp::$DATA, mrp::$REPARSE_POINT und mrp::$ATTRIBUTE_LIST.

Beim Defragmentieren von NTFS-Dateisystemvolumes ist das Defragmentieren eines virtuellen Clusters über die Zuordnungsgröße einer Datei hinaus zulässig.

Minimieren von Interaktionen zwischen Defragmentierung und Schattenkopien

Verschieben Sie Daten nach Möglichkeit in relativ zueinander ausgerichteten Blöcken in 16-KB-Schritten. Dadurch wird der Aufwand für das Kopieren beim Schreiben reduziert, wenn Schattenkopien aktiviert sind, da der Speicherplatz für Schattenkopien erhöht und die Leistung verringert wird, wenn die folgenden Bedingungen auftreten:

  • Die Größe des Bewegungsanforderungsblocks ist kleiner oder gleich 16 KB.
  • Das Verschiebendelta befindet sich nicht in Schritten von 16 KB.

Das Verschiebendelta ist die Anzahl von Bytes zwischen dem Beginn des Quellblocks und dem Start des Zielblocks. Anders ausgedrückt: Ein Block ab Offset X (on-disk) kann in einen Startoffset Y verschoben werden, wenn der absolute Wert von X minus Y ein gerades Vielfaches von 16 KB ist. Wenn Also 4-KB-Cluster angenommen werden, wird ein Wechsel von Cluster 3 zu Cluster 27 optimiert, aber ein Wechsel von Cluster 18 zu Cluster 24 nicht. Beachten Sie, dass mod(3,4) = 3 = mod(27,4). Mod 4 wird ausgewählt, da vier Cluster mit jeweils 4 KB 16 KB entsprechen. Daher führt ein Volume, das auf eine Clustergröße von 16 KB formatiert ist, dazu, dass alle Verschiebungsdateien optimiert werden.

Weitere Informationen zu Schattenkopien finden Sie unter Volume Shadow Copy Service.

Dateien, Streams und Streamtypen, die für die Defragmentierung unterstützt werden

Während die meisten Dateien mit dem FSCTL_MOVE_FILE-Steuerelementcode verschoben werden können, können nicht alle verschoben werden. Im Folgenden finden Sie eine Liste der Dateien, Streams und Streamtypen (auch attributtypcodes genannt), die von FSCTL_MOVE_FILE unterstützt werden. Andere Dateien, Streams und Streamtypen werden von FSCTL_MOVE_FILE nicht unterstützt.

Streamtypen, die für jede Datei oder jedes Verzeichnis unterstützt werden.

  • ::$DATA
  • ::$ATTRIBUTE_LIST
  • ::$REPARSE_POINT
  • ::$EA
  • ::$LOGGED_UTILITY_STREAM

**Windows 7, Windows Server 2008 R2, Windows Server 2008, Windows Vista, Windows Server 2003 und Windows XP: **::$EA und ::$LOGGED_UTILITY_STREAM werden vor Windows 8 und Windows Server 2012

Streamtypen, die für jedes Verzeichnis unterstützt werden.

  • ::$BITMAP
  • ::$INDEX_ALLOCATION

Im Folgenden werden die Systemdatei-, Stream- und Streamtypen aufgeführt, die von FSCTL_MOVE_FILE im Format "filename:streamname:$typename" unterstützt werden.

  • $MFT::$DATA
  • $MFT::$ATTRIBUTE_LIST
  • $MFT::$BITMAP
  • $AttrDef::$DATA
  • $AttrDef::$ATTRIBUTE_LIST
  • $Secure:$SDS:$DATA
  • $Secure::$ATTRIBUTE_LIST
  • $Secure:$SDH:$INDEX_ALLOCATION
  • $Secure:$SDH:$BITMAP
  • $Secure:$SII:$INDEX_ALLOCATION
  • $Secure:$SII:$BITMAP
  • $UpCase::$DATA
  • $UpCase::$ATTRIBUTE_LIST
  • $Extend:$I 30:$INDEX_ALLOCATION
  • $Extend::$ATTRIBUTE_LIST
  • $Extend:$I 30:$BITMAP
  • $Extend\$UsnJrnl:$J:$DATA
  • $Extend\$UsnJrnl::$ATTRIBUTE_LIST
  • $Extend\$UsnJrnl:$Max:$DATA
  • $Extend\$Quota:$Q:$INDEX_ALLOCATION
  • $Extend\$Quota::$ATTRIBUTE_LIST
  • $Extend\$Quota:$Q:$BITMAP
  • $Extend\$Quota:$O:$INDEX_ALLOCATION
  • $Extend\$Quota:$O:$BITMAP
  • $Extend\$ObjId:$O:$INDEX_ALLOCATION
  • $Extend\$ObjId::$ATTRIBUTE_LIST
  • $Extend\$ObjId:$O:$BITMAP
  • $Extend\$Reparse:$R:$INDEX_ALLOCATION
  • $Extend\$Reparse::$ATTRIBUTE_LIST
  • $Extend\$Reparse:$R:$BITMAP
  • $Extend\$RmMetadata:$I 30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata:$I 30:$BITMAP
  • $Extend\$RmMetadata::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Repair::$DATA
  • $Extend\$RmMetadata\$Repair::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Repair:$Config:$DATA
  • $Extend\$RmMetadata\$Txf:$I 30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata\$Txf::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Txf:$I 30:$BITMAP
  • $Extend\$RmMetadata\$Txf:$TXF_DATA:$LOGGED_UTILITY_STREAM
  • $Extend\$RmMetadata\$TxfLog:$I 30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata\$TxfLog::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$TxfLog:$I 30:$BITMAP
  • $Extend\$RmMetadata\$TxfLog\$Tops::$DATA
  • $Extend\$RmMetadata\$TxfLog\$Tops::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$TxfLog\$Tops:$T:$DATA
  • $Extend\$RmMetadata\$TxfLog\$TxfLog.blf::$DATA
  • $Extend\$RmMetadata\$TxfLog\$TxfLog.blf::$ATTRIBUTE_LIST