Defragmentera filer

När en fil skrivs till en disk kan filen ibland inte skrivas i sammanhängande kluster. Icke-sammanhängande kluster gör processen att läsa och skriva en fil långsammare. Ju längre ifrån varandra på en disk som de icke-sammanhängande klustren är, desto värre är problemet, på grund av den tid det tar att flytta läs- och skrivhuvudet på en hårddisk. En fil med icke-sammanhängande kluster är fragmenterad. För att optimera filer för snabb åtkomst kan en volym defragmenteras.

Defragmentering är processen att flytta runt delar av filer på en disk till defragmenteringsfiler, dvs. processen att flytta filkluster på en disk för att göra dem sammanhängande. Mer information finns i följande avsnitt:

Defragmentera en fil

I ett enkelt operativsystem med en uppgift är defragmenteringsprogramvaran den enda uppgiften och det finns inga andra processer att läsa från eller skriva till disken. Men i ett operativsystem med flera funktioner kan vissa processer läsa från och skriva till en hårddisk medan en annan process defragmenterar hårddisken. Tricket är att undvika skrivningar till en fil som defragmenteras utan att avbryta skrivprocessen under mycket lång tid. Att lösa det här problemet är inte trivialt, men det är möjligt.

För att tillåta defragmentering utan att kräva detaljerad kunskap om en filsystemdiskstruktur tillhandahålls en uppsättning med tre kontrollkoder. Kontrollkoderna innehåller följande funktioner:

  • Aktivera program för att hitta tomma kluster
  • Fastställa diskplatsen för filkluster
  • Flytta kluster på en disk

Kontrollkoderna hanterar också transparent problemet med att hämma och tillåta andra processer att läsa från och skriva till filer under flyttningar.

Dessa åtgärder kan utföras utan att hindra andra processer från att köras. De andra processerna har dock långsammare svarstider medan en diskenhet defragmenteras.

Så här defragmenterar du en fil:

  1. Använd FSCTL_GET_VOLUME_BITMAP-kontrollkoden för att hitta en plats på volymen som är tillräckligt stor för att acceptera en hel fil.

Observera

Om det behövs flyttar du andra filer för att skapa en plats som är tillräckligt stor. Helst finns det tillräckligt med oallokerade kluster efter den första omfattningen av filen som du kan flytta efterföljande omfattningar till utrymmet efter den första omfattningen.

  1. Använd FSCTL_GET_RETRIEVAL_POINTERS-kontrollkoden för att hämta en karta över den aktuella layouten för filen på disken.

  2. Navigera i den RETRIEVAL_POINTERS_BUFFER-struktur som returneras av FSCTL_GET_RETRIEVAL_POINTERS.

  3. Använd FSCTL_MOVE_FILE-kontrollkoden för att flytta varje kluster när du går igenom strukturen.

    Not

    Du kan behöva förnya antingen bitmappen eller hämtningsstrukturen, eller båda vid olika tidpunkter när andra processer skrivs till disken.

Två av de åtgärder som används i defragmenteringsprocessen kräver en referens till en volym. Endast administratörer kan få åtkomst till en volym, så bara administratörer kan defragmentera en volym. Ett program bör kontrollera rättigheterna för en användare som försöker köra defragmenteringsprogram och bör inte tillåta att en användare defragmenterar en volym om användaren inte har rätt rättigheter.

När du använder CreateFile för att öppna en katalog under defragmenteringen av en FAT- eller FAT32-filsystemvolym anger du värdet för GENERIC_READ åtkomstmask. Ange inte värdet för MAXIMUM_ALLOWED åtkomstmask. Åtkomst till katalogen nekas om detta görs.

Försök inte flytta allokerade kluster i ett NTFS-filsystem som sträcker sig bortom den klusteravrundade filstorleken, eftersom resultatet är ett fel.

Omparsningspunkter, bitmappar och attributlistor i NTFS-filsystemvolymer kan defragmenteras, öppnas för läsning och synkronisering och namnges med hjälp av -filen:namn:typ syntax; till exempel dirname:$i 30:$INDEX_ALLOCATION, mrp::$DATA, mrp::$REPARSE_POINT och mrp::$ATTRIBUTE_LIST.

När du defragmenterar NTFS-filsystemvolymer tillåts defragmentering av ett virtuellt kluster utöver allokeringsstorleken för en fil.

Minimera interaktioner mellan defragmentering och skuggkopior

När det är möjligt flyttar du data i block som är justerade i förhållande till varandra i steg om 16 kilobyte (KB). Detta minskar kostnaderna för kopiering vid skrivning när skuggkopior aktiveras, eftersom skuggkopieringsutrymmet ökar och prestandan minskar när följande villkor inträffar:

  • Blockstorleken för flyttbegäran är mindre än 16 kB.
  • Flyttdeltat är inte i intervaller om 16 KB.

Flyttdeltat är antalet byte mellan början av källblocket och början av målblocket. Med andra ord kan ett block som börjar vid förskjutning X (på disk) flyttas till en startförskjutning Y om det absoluta värdet för X minus Y är en jämn multipel på 16 kB. Om vi antar 4 KB-kluster optimeras alltså en övergång från kluster 3 till kluster 27, men en övergång från kluster 18 till kluster 24 kommer inte att göra det. Observera att mod(3,4) = 3 = mod(27,4). Mod 4 väljs eftersom fyra kluster med 4 KB vardera motsvarar 16 KB. En volym som är formaterad till en klusterstorlek på 16 KB resulterar därför i att alla flyttfiler optimeras.

Mer information om skuggkopior finns i Volume Shadow Copy Service.

Filer, strömmar och strömtyper som stöds för defragmentering

De flesta filer kan flyttas med hjälp av FSCTL_MOVE_FILE kontrollkod, men alla kan inte flyttas. Nedan visas listan över filer, strömmar och strömtyper (kallas även attributtypkoder) som stöds av FSCTL_MOVE_FILE. Andra filer, strömmar och strömtyper stöds inte av FSCTL_MOVE_FILE.

Dataströmtyper som stöds för alla filer eller kataloger.

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

Windows 7, Windows Server 2008 R2, Windows Server 2008, Windows Vista, Windows Server 2003 och Windows XP: ::$EA och ::$LOGGED_UTILITY_STREAM stöds inte före Windows 8 och Windows Server 2012

Stream-typer som stöds för alla kataloger.

  • ::$BITMAP
  • ::$INDEX_ALLOCATION

Här följer systemfils-, ström- och strömtyper som stöds av FSCTL_MOVE_FILE i formatet "filnamn:strömnamn:$typnamn".

  • $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:$I30:$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:$I30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata:$I30:$BITMAP
  • $Extend\$RmMetadata::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Repair::$DATA
  • $Extend\$RmMetadata\$Repair::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Repair:$Config:$DATA
  • $Extend\$RmMetadata\$Txf:$I30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata\$Txf::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Txf:$I30:$BITMAP
  • $Extend\$RmMetadata\$Txf:$TXF_DATA:$LOGGED_UTILITY_STREAM
  • $Extend\$RmMetadata\$TxfLog:$I30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata\$TxfLog::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$TxfLog:$I30:$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