3

この質問は、このトピックによるものです: c# でほんの数秒で巨大なダミー ファイルを作成する

xp/vista/seven の fsutil.exe をチェックして、膨大な量のダミー データをストレージ ディスクに書き込んだところ、プログラムによる方法と比較して、このような大きなファイルの書き込みにかかる時間が短くなりました。

.net を使用して同じことをしようとすると、fsutil.exe よりもかなり時間がかかります。

注:私は.netがネイティブコードを使用していないことを知っています。そのため、次のようにネイティブAPIでこの問題を確認しました:

long int size = DiskFree('L' - 64);
const char* full = "fulldisk.dsk";
__try{
Application->ProcessMessages();
HANDLE hf = CreateFile(full,
                       GENERIC_WRITE,
                       0,
                       0,
                       CREATE_ALWAYS,
                       0,
                       0);
SetFilePointer(hf, size, 0, FILE_BEGIN);
SetEndOfFile(hf);
CloseHandle(hf);
}__finally{
    ShowMessage("Finished");
    exit(0);

答えは.netの結果と同じでした。

しかし、fsutil.exe の助けを借りて、上記よりも短い時間しかかからないか、.net アプローチは 2 倍高速であると言います

例: .net で 400MB を書き込む場合、約 40 秒かかります。 fsutil.exe を使用した場合と同じ量で、約 20 秒以下かかります。

それについての説明はありますか?または、 fsutil.exe が使用する関数のうち、この重要な書き込み速度を持つ関数はどれですか?

4

4 に答える 4

5

fsutilが何をしているのか正確にはわかりませんが、上記で行ったよりも高速な大きなファイルを作成する2つの方法を知っています(または、必要な長さを求めてゼロを作成します。これは同じです。結果)。

これらのアプローチの問題は、書き込み時にファイルがゼロで埋められることです。

次のいずれかの方法でゼロフィルを回避できます。

  1. スパースファイルの作成。サイズは必要な場所にマークされていますが、データを書き込むまで、データは実際にはディスク上に存在しません。書き込まれていない領域のすべての読み取りはゼロを返します。
  2. SetFileValidData関数を使用して、最初にファイルをゼロにすることなく有効なデータ長を設定します。ただし、潜在的なセキュリティ問題のため、このコマンドには昇格された権限が必要です。
于 2009-12-12T12:18:59.113 に答える
2

最後のコメントに同意します。ミニフィルター ドライバーを試していて、コールバックで IRP_MJ_WRITE IRP をキャプチャしていました。cmd ラインまたは win32 アプリケーションからファイルを作成または書き込みすると、書き込みが停止するのがわかります。しかし、「fsutil file createnew ...」コマンドを使用してファイルを作成すると、書き込みが表示されません。NTFS ボリューム上の win2k8 r2 でこの動作が見られます。そして、私はそれがスパースファイルでもあるとは思いません(100%はわかりませんが)。おそらく、クラスタを割り当てずに MFT でサイズ プロパティを設定しています。fsutil は使用可能な空き容量を確認するため、ファイル サイズがディスクの空き容量よりも大きい場合は、エラー 1 が発生します。

また、FSCTL_GET_RETRIEVAL_POINTERS をファイルに送信するプログラムを実行し、ファイル全体のサイズに対して 1 つのエクステントを取得しました。しかし、私はそれがすべてのデータを取得していると信じています

于 2011-07-13T19:51:08.307 に答える
1

fsutil は NTFS と exFAT でのみ高速であり、FAT32 と FAT16 では高速ではありません。これは、ファイル システムによっては「初期化されたサイズ」の概念があり、高速なファイル初期化をサポートしているためです。これはクラスターを予約するだけで、クラスターをゼロにはしません。これは、ファイルにデータが書き込まれず、有効な読み取りがすべて 00 で満たされたバッファーを返すことをファイル システムに記録するためです。

于 2010-08-25T18:31:18.720 に答える
1

これはあり得ることです

  • アセンブラで書かれています (Raw blending speed)
  • これを行うためのネイティブ C/C++ コード
  • おそらく、これを行うための文書化されていないシステムコール、またはどこにも文書化されていないトリックです。

上記の 3 つのポイントには、非常に重要な要素が含まれている可能性があります。考えてみると、.NET コードが読み込まれると、ランタイムによってジットされます (わかりました。非常に高速なマシンを使用している場合、時間要素は目立たないでしょう)。 - ローエンドのペンティアムでは、読み込みが遅くて目立ちます)。

おそらく、C/C++ のいずれかで記述されている可能性があります。アセンブラで書かれていると驚くかもしれません。

これは自分で確認できます。実行可能ファイルのファイル サイズを調べて、.NET の実行可能ファイルと比較してください。ファイルが圧縮されていると主張するかもしれませんが、私はそうではないので、これを除外する傾向があります.

これがあなたの質問に答えてくれることを願っています。よろしくお願いします、トム。

于 2009-12-12T12:12:14.133 に答える