如何检查输出流的缓冲区类型?

4

使用 setvbuf() 函数,我们可以将一个 FILE* 流的缓冲类型更改为以下之一:

  • _IONBF (无缓冲)
  • _IOLBF (行缓冲)
  • _IOFBF (全缓冲)

例如,如果要将 stderr 设置为行缓冲,我们可以执行以下操作:

setvbuf(stderr, NULL, _IOLBF, 0);

是否有一种方法可以根据给定的输出流(使用文件描述符或 FILE 指针)确定当前缓冲区类型?

1个回答

3

这是不可能的。目前没有标准的方法来确定已打开FILE的当前缓冲特性。

Solaris引入了非标准函数,可用于GNU C库,其中在GNU C库中的stdio_ext.h中有一个__flbf函数,如果流是行缓冲,则返回非零值。

经过检查glibc源代码libio/iosetvbuf.c后,以下程序在我的平台上与GNU libc 2.31一起使用,但不应使用:

#include <stdio.h>

#ifdef __GLIBC__
#define _IO_UNBUFFERED        0x0002
#define _IO_LINE_BUF          0x0200
int getvbuf(FILE *f) {
    if (f->_flags & _IO_UNBUFFERED) {
        return _IONBF;
    } else if (f->_flags & _IO_LINE_BUF) {
        return _IOLBF;
    }
    return _IOFBF;
}
#else
#error This program works only with glibc.
#endif

const char *vbuf_to_str(int a) {
    switch (a) {
    case _IONBF: return "_IONBF";
    case _IOLBF: return "_IOLBF";
    case _IOFBF: return "_IOFBF";
    }
    return "unknown";
}

int main() {
    setvbuf(stderr, NULL, _IONBF, 0);
    printf("%s\n", vbuf_to_str(getvbuf(stderr)));
    setvbuf(stderr, NULL, _IOLBF, 0);
    printf("%s\n", vbuf_to_str(getvbuf(stderr)));
    setvbuf(stderr, NULL, _IOFBF, 0);
    printf("%s\n", vbuf_to_str(getvbuf(stderr)));
}

这是因为FILE是一种没有标准实现的类型吗? - Daniel Walker
1
“那”具体指什么?是的,“FILE”是不透明的类型。C标准没有规定其实现方式。我认为委员会的意图是程序员甚至不需要查询“FILE”的当前缓冲模式,所以他们没有提供这样的接口,因为这并不是必需的。但这只是我的猜测。 - KamilCuk
是的,这就是我的意思。没有标准方法来获取缓冲属性是因为这会对实现做出可能无效的假设吗? - Daniel Walker
“不需要”——直到需要为止,什么都不是必须的。 :-) - domsson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接