Ответ # 1: Это не медленнее.
Ответ # 2: Это зависит.
Для каждого байта, который вы читаете из файла, вы не хотите делать syscall (который включает контекстный переключатель в системах с защитой памяти). Вы, при первом доступе по размеру байта, читаете соответствующий объем данных (скажем, 4k) в память и обслуживаете первый байт вызывающему. При последующих чтениях размера байта вам не нужно вызывать ядро или вообще обращаться к файлу; вы просто передаете следующий байт из буфера, пока не будете читать другой блок 4k.
Это то, что стандартные вызовы библиотеки C (fread()
, fgetc()
, fgets()
и т. Д.) Делают по умолчанию. Вы можете проверить BUFSIZ
, чтобы получить размер буфера по умолчанию. Вы можете изменить размер буфера или вообще отключить буферизацию с помощью вызова setvbuf()
.
read()
не входит в стандартную библиотеку C, это системный вызов POSIX. В основном, это backend для стандартных вызовов библиотеки C в системах POSIX. (В системе Windows fgetc()
вместо этого вызывается Win32 API.) Таким образом, read()
не буферизует, а вызов его для блоков размером с байтом неэффективен. Если вы звоните read()
, вы обычно делаете это, потому что хотите сделать буферизацию самостоятельно.
Вообще говоря, не следует смешивать вызовы ввода-вывода POSIX и стандартной библиотеки. Используйте POSIX API для доступа на низкоуровневом уровне, используйте стандартную библиотеку для удобства переносов (и хорошую производительность по умолчанию).
Как вы определили, что это медленнее? –
[двойной] (http: //unix.stackexchange.com/questions/73264/why-read-is-slower-than-getc) –
Поскольку не буферизация – BLUEPIXY