質問

私はダウンロードアプリケーションを作成しています。ファイルが実際にダウンロードされる前に、ファイルのハードドライブの部屋を事前に表示したいと思います。 「だから、その観点から、私はこれを書いた。

// 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 相当の) データをディスクに書き出すため、まだ遅いです。

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

役に立ちましたか?

解決

FileStream.SetLength あなたが欲しいものです。構文:

public override void SetLength(
    long value
)

他のヒント

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

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

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

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

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