FileStream.Seek против буферизованного чтения - PullRequest
5 голосов
/ 06 декабря 2010

Мотивировано этим ответом Мне было интересно, что происходит под занавесом, если кто-то использует много FileStream.Seek(-1).

Для ясности я перепишу ответ:

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 хорошо кэширует, нос другой стороны, каждый ответ на «чтение файла в обратном направлении» включает чтение фрагментов байтов и работу с этим фрагментом.

Ответы [ 2 ]

6 голосов
/ 06 декабря 2010

Движение вперед или назад обычно не имеет большого значения.Данные файла считываются в кэш файловой системы после первого чтения, вы получаете копию из памяти в память на ReadByte ().Эта копия не зависит от значения указателя файла, пока данные находятся в кэше.Однако алгоритм кэширования работает исходя из предположения, что вы обычно читаете последовательно.Он пытается читать вперед, пока файловые сектора все еще находятся на одной дорожке.Обычно они есть, если диск сильно не фрагментирован.

Но да, это неэффективно.Вы получите два вызова pinvoke и API для каждого отдельного байта.В этом есть много служебных данных, и те же два вызова могут считывать, скажем, 65 килобайт с таким же объемом служебных данных.Как обычно, исправляйте это, только когда вы обнаружите, что это узкое место перф.

1 голос
/ 06 декабря 2010

Здесь указатель на Кэширование файлов в Windows

Поведение также может зависеть от того, где физически находится файл (жесткий диск, сеть и т. Д.), А также от локальной конфигурации /Оптимизация.

Еще одним важным источником информации является документация API CreateFile: Функция CreateFile

Существует хороший раздел под названием «Поведение кэширования», который говорит нам, по крайней мере, какВы можете влиять на кэширование файлов, по крайней мере, в неуправляемом мире.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...