Я пытаюсь проанализировать основную операцию чтения, используя ifstream с Procmon.
Часть кода, используемая для операции чтения, когда я пытался прочитать данные размером 16 КБ из файла:
char * buffer = new char[128000];
ifstream fileHandle("file.txt");
fileHandle.read(buffer, 16000);
cout << buffer << endl;
fileHandle.close();
В Procmon было 4 операции ReadFile со следующими деталями:
Смещение: 0, длина: 4,096, приоритет: обычный
Смещение: 4096, длина: 4096
Смещение: 8 192, длина: 4 096
Смещение: 12 288, длина: 4 096
Так значит ли это, что было 4 операции каждого размера 4 КБ? и если да, то почему это произошло вместо того, чтобы просто иметь одну операцию ReadFile размером 16 КБ.
Так значит ли это, что было 4 операции каждого размера 4 КБ?
Это именно то, что говорится.
и если да, то почему это произошло вместо того, чтобы просто иметь одну операцию ReadFile размером 16 КБ.
Просто так вы просили 16000 байт не значит ifstream
действительно может прочитать 16000 байт за одну операцию. Файловые системы обычно не допускают таких больших чтений, обычно есть ограничение. Даже если вы увеличите размер внутреннего буфера, ifstream
использует внутренне, это еще не гарантия того, что файловая система будет поддерживать больший размер чтения.
Контракт read()
является то, что он возвращает запрошенное количество байтов, если EOF / ошибка не встречается. КАК это достигается, что чтение внутри является деталью реализации. В этом случае, ifstream
пришлось прочитать четыре блока по 4 КБ, чтобы вернуть 16000 байт.
Так значит ли это, что было 4 операции каждого размера 4 КБ?
Да.
и если да, то почему это произошло вместо того, чтобы просто иметь одну операцию ReadFile размером 16 КБ.
Возможно, потому что стандартная библиотека, поставляемая с вашим компилятором, устанавливает размер буфера файловых потоков по умолчанию равным 4 КБ; так как read
операция должна проходить через буфер, она должна быть заполнена (через вызовы ОС) и очищена 4 раза, прежде чем удовлетворять ваш запрос. Обратите внимание, что вы можете изменить внутренний буфер fstream
с помощью fileHandle.rdbuf->pubsetbuf
.