2010-12-06 17 views
5

動かすthis answerFileStream.Seek(-1)のロットを使用するとカーテンの下で何が起こっているのだろうと思っていました。FileStream.Seek vs. Buffered Reading

using (var fs = File.OpenRead(filePath)) 
{ 
    fs.Seek(0, SeekOrigin.End); 

    int newLines = 0; 
    while (newLines < 3) 
    { 
     fs.Seek(-1, SeekOrigin.Current); 
     newLines += fs.ReadByte() == 13 ? 1 : 0; // look for \r 
     fs.Seek(-1, SeekOrigin.Current); 
    } 

    byte[] data = new byte[fs.Length - fs.Position]; 
    fs.Read(data, 0, data.Length); 
} 

個人的に私がバッファに2048バイトのように読んで、文字のためにそのバッファを検索しましたでしょう:私は答えを再投稿します。明確にするため

Reflectorを使用すると、内部的にはSetFilePointerが使用されていることがわかりました。

ファイルをキャッシュして後方に読むWindowsに関するドキュメントはありますか? Seek(-1)を連続して使用している場合、Windowsはバッファを「後方に」バッファして調べるか、現在の位置から先読みしますか?

一方で、大部分の人が良いキャッシングを行うWindowsに同意しますが、一方で "ファイルを逆方向​​に読む"にはすべてのチャンクを読み取ってそのチャンクで操作することが含まれます。

+1

深刻なピアレビューをやっていますか? – ChaosPandion

+0

@ChaosPandion:私はあなたのコメントを評価しなかった、私はちょうど興味があった。 – VVS

答えて

6

前向きと後ろ向きは、通常大きな違いはありません。ファイルデータは、最初の読み取り後にファイルシステムのキャッシュに読み込まれ、ReadByte()でメモリ間コピーが取得されます。そのコピーは、データがキャッシュ内にある限り、ファイルポインタの値には影響を受けません。ただし、キャッシュアルゴリズムは、通常は順番に読むことを前提としています。ファイルセクタが同じトラック上にある限り、先読みを試みます。ディスクが大量に断片化されていない限り、通常はそれらがあります。

しかし、はい、それは非効率的です。個々のバイトごとに2つのピンボケとAPI呼び出しでヒットします。同じ2つの呼び出しで、同じ量のオーバーヘッドで65キロバイトも読み取ることができるという点でかなりのオーバーヘッドがあります。いつものように、それがperfボトルネックであると分かったときにのみこれを修正してください。ここ

+0

ああ、p /発呼にかかる費用はかかりませんでした。それはすでにチャンクで読むのに十分な理由です。 – VVS

1

File Caching in Windows

上のポインタである現象は、物理的にファイル(等ハードディスク、ネットワーク)ならびにローカル設定/最適化が存在する場所に依存してもよいです。 CreateFile Function

私たちは、少なくともあなたは、少なくとも管理対象外の世界では、ファイルキャッシングに影響を与えることができる方法を説明します「キャッシュ動作」という名前の良い部分があります:

アンはまた、重要な情報源は、CreateFileのAPIドキュメントです。