Входная и выходная буферизация по умолчанию для fopen'd файлов?

Таким образом, поток ФАЙЛА может иметь оба входных и выходных буфера. Можно скорректировать использование потока вывода setvbuf (Я не знаю о любом методе для проигрывания с размером входного буфера и поведением).

Кроме того, по умолчанию буфер BUFSIZ (не уверенный, если это - POSIX или вещь C). Очень ясно, для чего это означает stdin/stdout/stderr, но каковы значения по умолчанию для недавно открытых файлов? Они буферизуются для обоих вводов и выводов? Или возможно всего один?

Если это буферизуется, действительно ли произведите, принимает значение по умолчанию, чтобы заблокировать или выровнять режим?

Править: Я сделал некоторые тесты, чтобы видеть, как ответ Jonathan Leffler влиял на программы реального мира. Кажется этим, если Вы делаете чтение затем запись. Запись вызовет неиспользованную часть входного буфера к отброшенному полностью. На самом деле, будет, некоторые ищут, которые сделаны для хранения вещей при правильных файловых смещениях. Я использовал эту простую тестовую программу:

/* input file contains "ABCDEFGHIJKLMNOPQRSTUVWXYZ" */
#include <stdio.h>
#include <stdlib.h>

int main() {

    FILE *f = fopen("test.txt", "r+b");
    char ch;
    fread(&ch, 1, 1, f);
    fwrite("test", 4, 1, f);
    fclose(f);
    return 0;
}

приведший к следующим системным вызовам:

read(3, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 4096) = 27 // attempt to read 4096 chars, got 27
lseek(3, -26, SEEK_CUR)                 = 1        // at this point, I've done my write already, so forget the 26 chars I never asked for and seek to where I should be if we really just read one character...
write(3, "test", 4)                     = 4        // and write my test
close(3)                                = 0

В то время как это ясно детали реализации, я нашел, что они были очень интересны до, как стандартная библиотека могла быть реализована. Спасибо Jonathan для Вашего проницательного ответа.

7
задан T.Rob 28 November 2011 в 23:06
поделиться

1 ответ

Один файловый поток имеет единственный буфер. Если файл используется как для ввода, так и для вывода, вы должны убедиться, что вы выполняете соответствующие операции (fseek () или эквиваленты) между операциями чтения и записи (или записи и чтения).

Буферизация стандартных каналов зависит от платформы.

Обычно stdout буферизируется по строке, когда вывод поступает на терминал. Однако, если stdout обращается к файлу или каналу, а не к терминалу, он обычно переключается на полную буферизацию.

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

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

Новые открытые файлы, как правило, полностью буферизуются. Конкретная реализация может изменить это на буферизацию строки, если устройство является терминалом.

Ваше предположение - что есть два буфера - неверно.


В разделе 7.19.3 C99 говорится:

При запуске программы предопределены три текстовых потока, и их не нужно открывать явно - стандартный ввод (для чтения обычного ввода), стандартный вывод (для запись стандартного вывода) и стандартной ошибки (для записи диагностического вывода). При первоначальном открытии стандартный поток ошибок не полностью буферизован; потоки стандартного ввода и вывода полностью буферизуются тогда и только тогда, когда можно определить, что поток не ссылается на интерактивное устройство.

Итак, как было изначально заявлено, stderr либо не буферизуется , либо буферизуется по строкам (буферизуется не полностью).

6
ответ дан 7 December 2019 в 09:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: