19

ダウンロードアプリケーションを作成しています。ファイルがかなり大きくなる可能性があるため、実際にダウンロードする前にハードドライブにファイル用のスペースを事前に割り当てたいと思います。「このドライブがいっぱいです。いくつかのファイルを削除して、もう一度やり直してください。 「」それで、その観点から、私はこれを書きました。

// Quick, and very dirty
System.IO.File.WriteAllBytes(filename, new byte[f.Length]);

少なくとも数百MB、または場合によってはGBのファイルをダウンロードし、ページファイルを完全に消去してシステムメモリを完全に強制終了しない場合でも、Windowsをスラッシング狂乱に陥れるまでは機能します。おっと。

それで、もう少し悟りを持って、私は次のアルゴリズムで着手しました。

using (FileStream outFile = System.IO.File.Create(filename))
{
    // 4194304 = 4MB; loops from 1 block in so that we leave the loop one 
    // block short
    byte[] buff = new byte[4194304];
    for (int i = buff.Length; i < f.Length; i += buff.Length)
    {
        outFile.Write(buff, 0, buff.Length);
    }
    outFile.Write(buff, 0, f.Length % buff.Length);
}

これはうまく機能し、最後のソリューションのメモリ障害の問題に悩まされることはありません。ただし、特に古いハードウェアでは、(GBに相当する可能性のある)データをディスクに書き出すため、まだ低速です。

問題はこれです:同じことを達成するためのより良い方法はありますか?1トンのデータを実際に書き出すのではなく、xサイズのファイルを作成し、ファイルシステムにスペースを割り当てるようにWindowsに指示する方法はありますか。私はファイル内のデータを初期化することをまったく気にしません(私が使用しているプロトコル-bittorrent-は送信するファイルにハッシュを提供します。したがって、ランダムに初期化されていないデータの最悪のケースは、幸運な偶然の一致とファイルの一部を取得することです正しい)。

4

3 に答える 3

29

FileStream.SetLengthは、必要なものです。構文:

public override void SetLength(
    long value
)
于 2008-09-19T02:01:07.350 に答える
5

ファイルを作成する必要がある場合は、おそらく次のようなことができると思います。

using (FileStream outFile = System.IO.File.Create(filename))
{
    outFile.Seek(<length_to_write>-1, SeekOrigin.Begin);
    OutFile.WriteByte(0);
}

length_to_write は、書き込むファイルのバイト単位のサイズです。C# の構文が正しいかどうかはわかりませんが (テストするコンピューター上ではありません)、過去に C++ で同様のことを行ったことがあり、うまくいきました。

于 2008-09-19T01:58:52.037 に答える
2

残念ながら、最後までシークするだけでは、これを実際に行うことはできません。これにより、ファイルの長さが巨大に設定されますが、実際にはストレージ用のディスク ブロックが割り当てられない場合があります。そのため、ファイルを書き込もうとすると、まだ失敗します。

于 2008-09-19T02:03:58.577 に答える