ファイルの最適化
ファイルをディスクに書き込むときに、ファイルを連続したクラスターに書き込むことができない場合があります。 連続しないクラスターは、ファイルの読み取りと書き込みのプロセスを遅くします。 不連続なクラスターがディスク上でより離れているほど、ハード ディスク ドライブの読み取り / 書き込みヘッドの移動に時間がかかり、問題が悪化します。 非連続なクラスターを含むファイルは フラグ付けされます。 高速なアクセスのためにファイルを最適化するには、ボリュームを最適化できます。
最適化とは、ファイルを最適化するためにディスク上のファイルの一部を移動するプロセスであり、これによりディスク上のファイル クラスターを移動して連続したものにするプロセスです。 詳細については、以下のセクションを参照してください。
ファイルの最適化
単純な単一タスク オペレーティング システムでは、最適化ソフトウェアのみがタスクであり、ディスクで読み取りまたは書き込みを行う他のプロセスはありません。 ただし、マルチタスク オペレーティング システムでは、ハード ディスク ドライブで読み取りや書き込みを行うプロセスもあれば、そのハード ディスク ドライブを最適化するプロセスもあります。 トリックとしては、非常に長い間書き込みプロセスを停止せずに最適化されているファイルへの書き込みを回避することです。 この問題を解決することは簡単ではありませんが、可能です。
ファイル システムのディスク構造に関する詳細な知識を必要とせずに最適化を可能にするために、3 つの制御コード セットが提供されています。 制御コードでは以下の機能が提供されます。
- アプリケーションで空のクラスターを検索できるようにする
- ファイル クラスターのディスクの場所を指定する
- ディスク上のクラスターを移動する
また、制御コードは、移動中に他のプロセスがファイルの読み取りと書き込みを行うことを禁止したり、許可したりする問題を透過的に処理します。
これらの操作は、他のプロセスの実行を妨げることなく実行できます。 ただし、ディスク ドライブの最適化中は、他のプロセスの応答時間が遅くなります。
ファイルを最適化するには:
- FSCTL_GET_VOLUME_BITMAP 制御コードを使用して、ボリューム上でファイル全体を受け入れるのに十分なサイズの場所を見つけます。
Note
必要に応じて、他のファイルを移動して、十分な大きさにします。 ファイルの最初のエクステントの後に十分な未割り当てクラスターがあり、その後のエクステントを最初のエクステントの後のスペースに移動できることが理想的です。
FSCTL_GET_RETRIEVAL_POINTERS 制御コードを使用して、ディスク上のファイルの現在のレイアウトのマップを取得します。
FSCTL_GET_RETRIEVAL_POINTERS によって返される RETRIEVAL_POINTERS_BUFFER 構造体をウォークします。
FSCTL_MOVE_FILE 制御コードを使用して、構造体をウォークしながら各クラスターを移動します。
Note
他のプロセスがディスクに書き込む際に、ビットマップまたは取得構造体、またはその両方を複数回更新することが必要になる場合があります。
最適化プロセスで使用される 2 つの操作には、ボリュームへのハンドルが必要です。 ボリュームへのハンドルを取得できるのは管理者のみであるため、管理者のみがボリュームを最適化できます。 アプリケーションは、最適化ソフトウェアの実行を試みるユーザーの権限を確認します。そして、ユーザーが適切な権限を持っていない場合、ユーザーがボリュームを最適化できないようにする必要があります。
CreateFile を使用して FAT または FAT32 ファイル システム ボリュームの最適化中にディレクトリを開く場合は、GENERIC_READ アクセス マスク値を指定します。 MAXIMUM_ALLOWED アクセス マスク値は指定しないでください。 ディレクトリへのアクセスが行われると、アクセスは拒否されます。
クラスターの切り上げファイル サイズを上回って拡張される NTFS ファイル システムに割り当てられたクラスターを移動しないでください。エラーが生じます。
NTFS ファイル システム ボリューム内で再解析したポイント、ビットマップ、属性リストは、最適化して読み取りと同期用に開き、file:name:type 構文を使用して名前を付けることができます。たとえば、dirname:$i 30:$INDEX_ALLOCATION、mrp::$DATA、mrp::$REPARSE_POINT、mrp::$ATTRIBUTE_LIST などです。
NTFS ファイル システム ボリュームを最適化する場合、ファイルの割り当てサイズを超える仮想クラスターの最適化ができます。
最適化とシャドウ コピー間の相互作用を最小限にする
可能な場合は、16 キロバイト (KB) 単位で互いに相対的に配置されたブロック内でデータを移動します。 これにより、シャドウ コピーが有効になっている場合の書き込み時のコピー オーバーヘッドが軽減されます。シャドウ コピー領域が増加し、次の条件が発生するとパフォーマンスが低下するためです。
- 移動要求のブロック サイズは 16 KB 未満です。
- 移動デルタは 16 KB 単位ではありません。
移動デルタは、ソース ブロックの開始点からターゲット ブロックの開始点までのバイト数です。 つまり、オフセット X (ディスク上) から始まるブロックは、X から Y の絶対値が 16 KB の偶数倍の場合、開始オフセット Y に移動できます。 そのため、4 KB のクラスターを想定すると、クラスター 3 からクラスター 27 への移動は最適化されますが、クラスター 18 からクラスター 24 への移動は最適化されません。 mod(3,4) = 3 = mod(27,4) であることに注意してください。 それぞれ 4 KB の 4 つのクラスターが 16 KB に相当するため、Mod 4 が選択されます。 そのため、16 KB のクラスター サイズにフォーマットされたボリュームでは、すべての移動ファイルが最適化されます。
シャドウ コピーの詳細については、「ボリュームのシャドウ コピー サービス」を参照してください。
最適化でサポートされるファイル、ストリーム、ストリームの種類
ほとんどのファイルは FSCTL_MOVE_FILE 制御コードを使用して移動できますが、すべてを移動できるわけではありません。 FSCTL_MOVE_FILE でサポートされているファイル、ストリーム、ストリームの種類 (別称は属性型コード) の一覧を次に示します。 その他のファイル、ストリーム、ストリームの種類は、FSCTL_MOVE_FILE によってサポートされません。
任意のファイルまたはディレクトリでサポートされるストリームの種類。
- ::$DATA
- ::$ATTRIBUTE_LIST
- ::$REPARSE_POINT
- ::$EA
- ::$LOGGED_UTILITY_STREAM
Windows 7、Windows Server 2008 R2、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: ::$EA および ::$LOGGED_UTILITY_STREAM は、Windows 8 および Windows Server 2012 以前はサポートされていません
任意のディレクトリでサポートされるストリームの種類。
- ::$BITMAP
- ::$INDEX_ALLOCATION
「filename:streamname:$typename」形式の FSCTL_MOVE_FILE でサポートされるシステム ファイル、ストリーム、およびストリームの種類を次に示します。
- $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:$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