11

ファイルを非同期で効率的に拡張する方法を探しています。

サポート ドキュメントでは、Windows NT、Windows 2000、および Windows XP で非同期ディスク I/O が同期として表示されると次のように述べています。

注: アプリケーションは、SetFileValidData 関数を使用してファイルの有効なデータ長を変更し、WriteFile を発行することによって、前述の書き込み操作を非同期にすることができます。

MSDN ではSetFileValidData、 の関数ですSets the valid data length of the specified file

しかし、「有効なデータ」とは何かをまだ理解していません。それとファイルのサイズの違いは何ですか?

と を使用SetFilePointerExSetEndOfFileてファイル サイズを拡張できますが、これはどのように行うのSetFileValidDataですか?

SetFileValidDataファイルサイズより大きい引数は入力できません。この場合、 の生きている意味はSetFileValidData何ですか?

4

4 に答える 4

25

を使用SetEndOfFileしてファイルの長さを増やすと、論理ファイルの長さが変更され、必要なディスク領域が割り当てられますが、ファイルの新しい部分に対応するディスク セクターに実際にデータが物理的に書き込まれることはありません。有効なデータ長はそのままです。

これは、 を使用SetEndOfFileして非常に大きなファイルを非常に迅速に作成できることを意味します。また、ファイルの新しい部分から読み取ると、ゼロが得られます。ファイルの新しい部分に実際のデータを書き込むと、有効なデータ長が増加します。

スペースを確保したいだけで、ファイルにデータを順番に書き込む場合は問題ありません。しかし、ファイルを非常に大きくして、すぐにその末尾近くにデータを書き込むと、ファイルの新しい部分にゼロを書き込む必要があり、これには長い時間がかかります。実際にファイルにゼロを含める必要がない場合は、 を使用SetFileValidDataしてこの手順をスキップできます。ファイルの新しい部分には、以前に削除されたファイルからのランダム データが含まれます。

補遺:

  • スパース ファイルのルールは異なります。

  • 非特権ユーザーが読み取りアクセス権を持つファイルには使用しないでください。SetFileValidDataこれにより、他のユーザーが所有する削除済みファイルからコンテンツが漏洩する可能性があります。

于 2012-09-03T03:08:26.653 に答える
6

SetEndOfFile()ディスク上の割り当てられたセクターにゼロを書き込まないことに注意してください。MFT レコード内にスペース ポインターを割り当ててから、ファイル システム全体のスペース ビットマップを更新するだけです。ただし、OS または FS は、有効な/論理的なファイルの長さを MFT レコードに記録します。

ファイルを 1GB から 2GB に拡大すると、追加された 1GB はすべてゼロになるはずですが、FS はディスクにゼロを書き込みません。このファイルの有効な長さを参照して、1GB がゼロであることを認識します。この拡大された 1GB 部分から読み取ろうとすると、RAM に直接ゼロが埋め込まれ、アプリケーションにフィードバックされます。ただし、この 1GB 部分内に任意のバイトを書き込む場合、FS は元の 1GB オフセットからアプリケーションが書き込もうとしている現在のポインターまでゼロで埋める必要がありますが、現在の場所から末尾までの他のバイトは埋めません。ファイル。一方、有効/論理的な長さは 0 から現在の場所までであると記録され、物理サイズと割り当てられたサイズは 2GB のままです。

ただし、 を使用するSetFileValidData()と、FS は有効な長さを直接 2GB に設定し、わざわざゼロを埋めません。どの場所に書き込んでも書き込みますが、どの場所から読み取っても、ファイルがそのディスク領域に拡張される前に他のアプリケーションによって以前に生成されたガベージ データを読み取る可能性があります。

于 2013-11-05T00:38:37.810 に答える
-1

ターゲットファイルに予約済みのディスクスペースを実際に割り当てているSenEndofFileわけではなくSetFileValidData、ジョブを担当しているようです。

MSDNを参照し、

SetFileValidData 関数を使用すると、非常に特殊な状況で大きなファイルを作成できるため、後続のファイル I/O のパフォーマンスを他の方法よりも向上させることができます。具体的には、ファイルの拡張部分が大きく、データベース タイプのアプリケーションなどでランダムに書き込まれる場合、拡張してファイルに書き込むのにかかる時間は、SetEndOfFile を使用してランダムに書き込むよりも速くなります。

SetEndOfFile本当にスペースを割り当てると、ランダムに書き込むときSetFileValidDataよりも何もうまくいきません。SetEndOfFileそのため、実際の割り当てを行いSetEndOfFileながら、穴のあるスパースファイルを作成するだけです。SetFileValidData

于 2013-01-27T03:24:40.033 に答える