首页 > 解决方案 > 为什么输入函数不能跟随输出函数,反之亦然?

问题描述

我的教科书说:

“如果没有对 fflush、fseek、fsetpos 或 rewind 的干预调用,输入函数不能跟随输出函数,反之亦然。流 I/O 的第一个限制可以通过采用在每次输入操作之前刷新缓冲区的规则来解决。然而,解决第二个限制的唯一方法是在同一个打开的套接字描述符上打开两个流,一个用于读取,一个用于写入。”

所以我的问题是:

  1. 为什么输入函数不能跟随输出函数,反之亦然?
  2. 为什么不能通过添加 fflush 操作来修复第二个限制?

标签: cio

解决方案


C 标准说了一些类似的话,你的书大概是在解释它所说的:

C11 ¶7.21.5.3fopen函数

¶7 当文件以更新模式打开时(' +' 作为上述模式参数值列表中的第二个或第三个字符),可以在关联的流上执行输入和输出。但是,如果没有对函数fflush或文件定位函数(fseekfsetposrewind输入操作遇到文件结尾。在某些实现中,使用更新模式打开(或创建)文本文件可能会打开(或创建)二进制流。

这些规则允许图书馆控制事情。它可能必须清理由 推回的字符ungetc(),或安排刷新输出,以便可以正常完成输入,或其他任何事情。请注意,这些规则适用于文件流 ( FILE *)。大多数情况下,当您使用套接字时,您使用的是文件描述符 ( int),而不是文件流,这些规则根本不适用。

请注意,这fseek(fp, 0, SEEK_CUR)是一个定位操作,它会将输入位置留在原处(从当前偏移量中寻找零字节),除了丢失由ungetc().

与 using 相比, usingfflush()是一种笨拙的操作方式fseek()

使用套接字,单个文件描述符用于读取和写入远程方。但是,因为文件描述符函数没有缓冲,所以不会混淆如何处理已读取但尚未使用的数据(通过标准 I/O 流读取很容易发生),也不会混淆关于如何处理已写入 I/O 缓冲区但尚未发送到远程的数据。此外,与磁盘文件不同,套接字不是可查找的设备。管道、FIFO、终端和许多其他非磁盘、非磁带设备也是不可查找的。这并不能免除您遵守规则的责任,但可更新的流通常用于磁盘等设备,您可以在其中读回您所写的内容,而对于不可搜索的设备则不然。

因此,如果您确实需要用于套接字 I/O 的文件流,您可能确实希望使用两个单独的流,一个仅用于读取,一个仅用于写入。在 POSIX 系统上,您可以使用dup()dup2()创建套接字文件描述符的副本,然后使用fdopen()两次来创建读取和写入流。


推荐阅读