(注意:这不是如何刷新 a 的问题write()
。可以这么说,这是它的另一端。)
是否可以清空包含要读取的数据的文件描述符而不必这样read()
做?您可能对数据不感兴趣,因此阅读所有数据会浪费您可能有更好用途的空间和周期。
如果在 POSIX 中不可能,是否有任何操作系统有任何不可移植的方法来做到这一点?
更新:请注意,我说的是文件描述符,而不是流。
(注意:这不是如何刷新 a 的问题write()
。可以这么说,这是它的另一端。)
是否可以清空包含要读取的数据的文件描述符而不必这样read()
做?您可能对数据不感兴趣,因此阅读所有数据会浪费您可能有更好用途的空间和周期。
如果在 POSIX 中不可能,是否有任何操作系统有任何不可移植的方法来做到这一点?
更新:请注意,我说的是文件描述符,而不是流。
如果您正在处理tty,请查看tcflush()
:
#include <termios.h>
int tcflush(int fildes, int queue_selector);
成功完成后,tcflush() 丢弃写入 fildes(与终端关联的打开文件描述符)引用的对象但未传输的数据,或接收但未读取的数据,具体取决于 queue_selector [...]
对于 POSIX,使用lseek(2)
或lseek64(3)
向前搜索。对于 Windows,使用SetFilePointer()
或SetFilePointerEx()
。
如果您知道要跳过的字节数,则可lseek(fd, n, SEEK_CUR);
以为 POSIX 系统执行此操作。对于对象fseek()
也有。FILE *
在 POSIX 中,我认为您可以安全地查找文件末尾,其想法是,如果稍后写入更多数据,以便使数据超过 设置的位置lseek()
,您现在将能够读取更多数据。
带有 GNU C 库 2.5 或更高版本的 Linux 2.6.17 或更高版本包含splice()
系统调用,可用于将数据从一个文件描述符发送到另一个文件描述符,而无需将其复制到用户空间。这可用于通过简单地打开源文件描述符中的数据并将其插入文件描述符/dev/null
来丢弃数据。splice
/dev/null
流有 fclean 可用,它刷新写缓冲区,并将读缓冲区返回给 IO 系统。
http://www.gnu.org/software/hello/manual/libc/Cleaning-Streams.html
如果您真正想要做的是跳过字节,则重新定位文件指针是正确的操作。只需向前跳过您不想阅读的字节数。
http://www.gnu.org/software/hello/manual/libc/File-Position-Primitive.html#File-Position-Primitive
read() 和 flush() 都不是标准 C 或 C++ 的一部分,但当然没有一个标准函数支持输入流的刷新。我猜这反映了底层操作系统中不可用的东西。避免完全阅读某些内容的正常方法是使用某种 seek() 函数跳过它。
据此,一个 POSIX 系统会在上面做这件事fflush(stream);
。
对于打开读取的流,如果文件还没有处于EOF,并且文件可以查找,则需要调整底层打开文件描述的文件偏移量,以便对打开文件描述的下一个操作处理从被刷新的流中读取或写入的最后一个字节之后的字节。
BSD 引入fpurge()
,Solaris 和 glibc 引入__fpurge()
。
从手册页:
#include <stdio.h>
#include <stdio_ext.h>
void __fpurge(FILE *stream);
函数 __fpurge() 清除给定流的缓冲区。对于输出流,这会丢弃任何未写入的输出。对于输入流,这将丢弃从底层对象读取但尚未通过 getc(3) 获得的任何输入;这包括通过ungetc(3) 推回的任何文本。
函数 __fpurge() 的作用完全相同,但没有返回值。
但是请注意:
这些功能是非标准的,不可移植。fpurge() 函数是在 4.4BSD 中引入的,在 Linux 下不可用。函数 __fpurge() 是在 Solaris 中引入的,并且存在于 glibc 2.1.95 及更高版本中。
如果您正在使用文件描述符,则可以先从描述符中获取 aFILE*
。
int fd;
/* ... */
FILE* fp = fdopen(fd, "r");
/* ... */
__fpurge(fp);