C 风格文件输入/输出 (std::fflush)(std::fwide)(std::setbuf)(std::setvbuf)

文件访问

将输出流与实际文件同步

std::fflush

int fflush( std::FILE* stream );

对于输出流(和最近操作为输出的更新流),将来自 stream 缓冲区的未写入数据写入关联的输出设备。

对于输入流(和最近操作为输入的更新流),行为未定义。

stream 为空指针,则冲入所有打开的输出流,包含在库包内操作,或其他情况下程序不能直接访问的流。

参数

stream-要写入的文件流

返回值

成功时返回零。否则返回 EOF 并设置文件流的错误指示器。

注意

POSIX 通过定义其在输入流上的效果扩展 fflush 的规定,只要该流表示文件或另一可寻位设备:该情况下重定位 POSIX 文件指针以匹配 C 流指针(等效地撤销任何读缓冲)并舍弃任何未从流回读的 std::ungetc 或 std::ungetwc 的效果。

在宽字符 I/O 和窄字符 I/O 间切换文件流

std::fwide

int fwide( std::FILE* stream, int mode );

mode > 0 ,则试图令 stream 为宽面向。若 mode < 0 ,则试图令 stream 为字节面向。若 mode==0 ,则只查询流的当前面向。

若流的当前面向已决定(通过执行输出或通过之前调用 fwide ),则此函数不做任何事。

参数

stream-指向要修改或查询的 C I/O 流的指针
mode-大于零的整数值设置流为宽,小于零者设置流为窄,零值仅查询

返回值

若此调用后流为宽面向则为大于零的整数,若此调用后流为字节面向则为小于零的整数,若流无面向则为零。

为文件流设置缓冲区

std::setbuf

void setbuf( std::FILE* stream, char* buffer );

为 C 流 stream 上进行的 I/O 操作设置内部缓冲区。

buffer 非空,则等价于 std::setvbuf(stream, buffer, _IOFBF, BUFSIZ) 。

buffer 为空,则等价于 std::setvbuf(stream, NULL, _IONBF, 0) ,这会关闭缓冲。

参数

stream-要设置缓冲区的文件流
buffer-指向文件流所用的缓冲区的指针。若提供 NULL ,则关闭缓冲。若它非空,则数组必须足以保有至少 BUFSIZ 个字符

返回值

(无)

注意

若 BUFSIZ 不是适合的缓冲区大小,则能用 std::setvbuf 更改它。

std::setvbuf 亦应当用于检测错误,因为 std::setbuf 不指示成功或失败。

此函数仅可在已将 stream 关联到打开的文件后,但要在任何其他操作(除了对 std::setbuf/std::setvbuf 的失败调用)前使用。

一个常见错误是设置 stdin 或 stdout 的缓冲区为生存期在程序终止前结束的数组:

为文件流设置缓冲区与其大小

std::setvbuf

int setvbuf( std::FILE* stream, char* buffer, int mode, std::size_t size );

 以 mode 所指示值更改给定文件流 stream 的缓冲模式。另外,

  • buffer 为空指针,则重设内部缓冲区大小为 size
  • buffer 不是空指针,则指示流使用始于 buffer 而大小为 size 的用户提供缓冲区。必须在 buffer 所指向的数组的生存期结束前(用 fclose )关闭流。成功调用 setvbuf 后,数组内容不确定,而任何使用它的尝试是未定义行为。

参数

stream-要设置缓冲的文件流
buffer-指向要使用的流缓冲区的指针,或若仅更改大小和模式则为空指针
mode-使用的缓冲模式。它能是下列值之一:
_IOFBF全缓冲:当缓冲区为空时,从流读入数据。或者当缓冲区满时,向流写入数据。
_IOLBF行缓冲:每次从流中读入一行数据或向流中写入一行数据。
_IONBF无缓冲:直接从流中读入数据或直接向流中写入数据,缓冲设置无效。
size-缓冲区的大小

返回值

成功时为 ​0​ ,失败时为非零。

注意

此函数仅可在已将 stream 关联到打开的文件后,但要在任何其他操作(除了对 std::setbuf/std::setvbuf 的失败调用)前使用。

不是所有 size 字节都需要用于缓冲:实际缓冲区大小通常向下取整到 2 的倍数、页面大小的倍数等。

多数实现上,行缓冲仅对终端输入流可用。

一个常见错误是设置 stdin 或 stdout 的缓冲区为生存期在程序终止前结束的数组:

调用示例

#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <sys/stat.h>

int main()
{
    std::FILE* fp = std::fopen("test.txt", "r");
    if (!fp)
    {
        std::perror("fopen");
        return 1;
    }

    struct stat stats;
    if (fstat(fileno(fp), &stats) == -1)  // 仅限 POSIX
    {
        std::perror("fstat");
        return 1;
    }

    std::cout << "BUFSIZ is " << BUFSIZ << ", but optimal block size is "
              << stats.st_size << '\n';
    if (std::setvbuf(fp, NULL, _IOFBF, stats.st_size) != 0)
    {
        perror("setvbuf failed"); // POSIX 版本设置 errno
        return 1;
    }

    int ch;
    while ((ch = std::fgetc(fp)) != EOF); // 读取整个文件:用 truss/strace 观察
    // 所用的 read(2) syscall
    std::fclose(fp);
    return 0;
}
输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值