при использовании другого дескриптора файла, почему результат отличается? (системное программирование) - PullRequest
0 голосов
/ 31 октября 2018

Я изучаю описание файлов и понял, что если я использую функцию dup2() результат будет другим.

Первый фрагмент ...

int main(void){
    char buf1[BUFSIZ] = "I am low\n";

    printf("i am high\n");
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));

    return 0;
}

... дает следующий результат:

i am high
i am low 
i am low
i am low

Но второй фрагмент ...

int main(void){
    int fd = open("dupout",O_CREAT | O_WRONLY, 0655);
    char buf1[BUFSIZ] = "I am low\n";
    dup2(fd, 1);

    printf("i am high\n");
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    close(fd);

    return 0;
}

... производит следующее содержимое в dupout:

i am low 
i am low
i am low
i am high

Почему результаты отличаются?

1 Ответ

0 голосов
/ 31 октября 2018

объяснить:

Буфер

IO имеет три типа full buffer, line buffer и no buffer.

Первый пример:

По умолчанию stdout равно line buffer, означает, что при заполнении буфера или при достижении \n буфер будет сброшен.

int main(void){
    char buf1[BUFSIZ] = "I am low\n";
    printf("i am high\n");
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    return 0;
}

Выход:

i am high
I am low
I am low
I am low

Но когда мы изменим его на:

int main(void){
    char buf1[BUFSIZ] = "I am low\n";
    printf("i am high");   // no '\n'
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    return 0;
}

Выход:

I am low
I am low
I am low
i am high

продолжить: изменить на:

int main(void){
    char buf1[BUFSIZ] = "I am low\n";
    printf("i am high"); // no '\n'
    fflush(stdout);// flush
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    return 0;
}

Выход:

i am highI am low
I am low
I am low

Второй пример:

По умолчанию file IO равно full buffer, означает, что при заполнении буфера буфер будет сбрасываться.

int main(void){
    int fd = open("dupout",O_CREAT | O_WRONLY, 0655);
    char buf1[BUFSIZ] = "I am low\n";
    dup2(fd, 1);

    printf("i am high\n");
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    close(fd);

    return 0;
}

Выход:

I am low
I am low
I am low
i am high

Но когда мы изменим его на:

int main(void){
    int fd = open("dupout",O_CREAT | O_WRONLY, 0655);
    char buf1[BUFSIZ] = "I am low\n";
    dup2(fd, 1);

    printf("i am high\n");
    fflush(stdout);
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    close(fd);

    return 0;
}

Выход:

i am high
I am low
I am low
I am low

          old

Из-за буфера ввода-вывода. Если вы добавите setvbuf(stdout, NULL, _IONBF, 0); до printf, результат будет правильным. Строка означает, что нет буфера ввода-вывода.

Следующее все code:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>

int main(void){
    int fd = open("dupout",O_CREAT | O_WRONLY, 0655);
    char buf1[BUFSIZ] = "I am low\n";
    dup2(fd, 1);

    setvbuf(stdout, NULL, _IONBF, 0);
    printf("i am high\n");
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    write(1, buf1, strlen(buf1));
    close(fd);

    return 0;
}
...