fsutil.exe は、プログラムで実行するよりも巨大なファイルをディスクに書き込むのに時間がかからないのはなぜですか?

StackOverflow https://stackoverflow.com/questions/1893200

  •  19-09-2019
  •  | 
  •  

質問

この質問はこのトピックに従っています: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 が使用するどの関数が書き込み速度に重要な影響を与えるのでしょうか?

役に立ちましたか?

解決

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

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

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

  1. スパースファイルを作成します。サイズは必要な場所にマークされますが、データは書き込むまで実際にはディスク上に存在しません。書き込まれていない領域を読み取ると、すべてゼロが返されます。
  2. の使用 SetFileValidData 最初にファイルをゼロにせずに有効なデータ長を設定する関数。ただし、セキュリティ上の問題が発生する可能性があるため、このコマンドには昇格されたアクセス許可が必要です。

他のヒント

私は最後のコメントに同意します。私は、ミニフィルタードライバーで実験され、コールバックでIRP_MJ_WRITE IRPを取り込みました。私が作成またはCMDラインやWin32アプリケーションからファイルに書き込むとき、私は書き込みがダウンして来るのを見ることができます。しかし、ときに私が使用してファイルを作成し、「ファイルcreatenew FSUTIL ...」コマンドで、私はすべての書き込みが表示されません。私は、NTFSボリューム上win2k8 R2でこの振る舞いを見ています。そして、私はそれがいずれかのスパースファイルである(100%確実ではないが)ないと思います。これはおそらく、任意のクラスタを割り当てずにMFTでのサイズプロパティを設定しています。 FSUTILは、利用可能な空き容量をチェックしますので、ファイルサイズがディスク上の空き領域よりも大きい場合は、エラー1を取得します。

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

これはあり得ることだ

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

上記の 3 つの点には、非常に重要な要素がある可能性があります。よく考えてみると、.NET コードがロードされると、ランタイムによってジットが発生します (非常に高速なマシンを使用している場合、時間要素は目立たないでしょう) - 低位エンドの Pentium では、ロードが遅くなり、顕著になる可能性があります)。

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

これは自分で確認できます。実行可能ファイルのファイル サイズを調べて、.NET の実行可能ファイルと比較してください。ファイルが圧縮されていると主張する人もいるかもしれませんが、私は圧縮しているとは思えないので、これを除外したいと考えていますが、Microsoft は実行可能ファイルの圧縮ビジネスに関してそこまでは考えていないと思います。

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

FSUTILはNTFSとexFATの上ではなく、FAT32、FAT16に速いだけです いくつかのファイルシステムは、「初期化されたサイズ」concesptを持っているため、高速なファイル初期化をサポートするためです。それは何もデータがファイルに書き込まれなかったファイルシステムでは、有効なノート読み込みがすべて00で満たされたバッファを返しますので、これは単に、クラスタを留保しますが、それらをゼロにしません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top