2010-12-06 13 views
5

Motiviert von this answer Ich frage mich, was passiert unter dem Vorhang, wenn man viele FileStream.Seek(-1) verwendet.FileStream.Seek vs. Buffered Reading

Aus Gründen der Klarheit werde ich die Antwort umbuchen:

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); 
} 

Persönlich würde ich wie 2048 Bytes in einen Puffer gelesen und gesucht, die Puffer für den Saibling.

Mit Reflektor Ich fand heraus, dass intern die Methode SetFilePointer verwendet.

Gibt es Dokumentation über Windows-Caching und das Rückwärtslesen einer Datei? Speichert Windows "rückwärts" und fragt den Puffer ab, wenn fortlaufend Seek(-1) verwendet wird, oder liest er von der aktuellen Position aus voraus?

Es ist interessant, dass auf der einen Seite die meisten Leute damit einverstanden sind, dass Windows gutes Caching macht, aber auf der anderen Seite beinhaltet jede Antwort auf "Datei rückwärts lesen" das Lesen von Brocken von Bytes und das Arbeiten mit diesem Brocken.

+1

Doing serious Peer Review huh? – ChaosPandion

+0

@ChaosPandion: Ich habe deinen Kommentar nicht bewertet, ich war nur neugierig. – VVS

Antwort

6

Vorwärts vorwärts oder rückwärts macht normalerweise keinen großen Unterschied. Die Dateidaten werden nach dem ersten Lesevorgang in den Dateisystemcache eingelesen. Sie erhalten eine Speicherkopie auf ReadByte(). Diese Kopie reagiert nicht auf den Dateizeigerwert, solange sich die Daten im Cache befinden. Der Caching-Algorithmus funktioniert jedoch unter der Annahme, dass Sie normalerweise sequenziell lesen würden. Es wird versucht, voraus zu lesen, solange sich die Dateisektoren noch auf derselben Spur befinden. Sie sind normalerweise, es sei denn, die Festplatte ist stark fragmentiert.

Aber ja, es ist ineffizient. Sie werden mit zwei Pinvoke und API-Aufrufe für jedes einzelne Byte getroffen. Es gibt eine gewisse Menge an Overhead in diesem, die gleichen zwei Anrufe könnten auch sagen, 65 Kilobyte mit der gleichen Menge an Overhead. Wie üblich, behebe dies nur, wenn du feststellst, dass es ein perfekter Flaschenhals ist. Hier

+0

Ah, habe die Kosten für p/activing nicht berücksichtigt. Das ist schon Grund genug, um in Blöcken zu lesen. – VVS

1

ist ein Zeiger auf File Caching in Windows

Das Verhalten kann auch davon abhängig, wo physisch befindet, die Datei (Festplatte, Netzwerk, etc.) sowie die lokale Konfiguration/Optimierung.

Eine ebenfalls wichtige Informationsquelle ist die Createfile-API-Dokumentation: CreateFile Function

Es gibt einen guten Abschnitt „Caching-Verhalten“ genannt, die wir zumindest sagt, wie Sie Datei-Caching beeinflussen können, zumindest in der nicht verwalteten Welt.

Verwandte Themen