Fflush на файл - PullRequest
       10

Fflush на файл

2 голосов
/ 11 июня 2019

Наличие простого кода с сайта cplusplus.com

#include <stdio.h>

char mybuffer[80];

int main() {
    FILE *pFile;
    pFile = fopen("example.txt","r+");
    if (pFile == NULL)
        perror("Error opening file");
    else {
        fputs("test",pFile);
        fflush(pFile);    // flushing or repositioning required
        fgets(mybuffer, 80, pFile);
        puts(mybuffer);
        fclose(pFile);
        return 0;
    }
}

Мне интересно, что на самом деле fflush делает в случае file в качестве аргумента, как в приведенном вышекод, потому что результат одинаков с и без строки fflush(pFile) - en пустой буфер (ничего на выходе).

PS: я запускаю код в Linux gcc (6.3.0)

Ответы [ 2 ]

5 голосов
/ 11 июня 2019

Из стандарта C18:

7.21.5.3 функция fopen

Синопсис

#nclude <stdio.h>
FILE *fopen(const char * restrict filename,
            const char * restrict mode);          

Описание

...

7 Когда файл открывается в режиме обновления (+ в качестве второго или третьего символа в приведенном выше списке значений аргумента mode), ввод и вывод могут выполняться в связанном потоке. Однако за выводом не должен следовать непосредственно ввод без промежуточного вызова функции fflush или функции позиционирования файла (fseek, fsetpos или rewind), и за вводом не должен следовать непосредственно вывод без промежуточного вызова функции позиционирования файла, если только операция ввода не сталкивается с концом файла. Открытие (или создание) текстового файла в режиме обновления может вместо этого открыть (или создать) двоичный поток в некоторых реализациях.

Вот шаги, выполняемые размещенным кодом

  • файл example.txt открывается в режиме чтения и обновления.

  • 4 байта (text) записываются в файл, перезаписывая первые 4 байта файла.

  • буфер потока сбрасывается с fflush(), позволяя переключать режим с записи на чтение. Вот к чему относится комментарий: // flushing or repositioning required

  • программа переключается в режим чтения без изменения позиции и пытается прочитать до 79 байтов из позиции 4 в файле, останавливаясь на новой строке. Если никакие байты не могут быть прочитаны, возвращается NULL.

  • эта строка выводится на стандартный вывод. Однако обратите внимание, что если файл содержал 4 байта или меньше, fgets(mybuffer, 80, pFile) завершается с ошибкой и возвращает NULL, оставляя массив mybuffer в неопределенном состоянии, что приводит к неопределенному поведению puts(mybuffer);.

  • файл закрыт

0 голосов
/ 11 июня 2019

fflush() обычно не требуется, когда вы читаете и пишете один и тот же поток stdio. fputs() и fgets() оба обращаются к одному и тому же буферу ввода / вывода, поэтому очистка в этом случае обычно не требуется.

Однако есть некоторые ограничения. Несмотря на то, что используется один и тот же буфер, вам нужно что-то сделать для синхронизации между записью и чтением. Это может быть fflush(), но также будет синхронизироваться, если вы используете fseek(). И если вы хотите прочитать то, что вы только что написали, вы должны использовать fseek(), чтобы вернуться туда, где вы начали писать; который будет синхронизироваться без необходимости fflush().

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

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