没有read()清空或“刷新”文件描述符?

时间:2009-12-17 19:56:24

标签: c flush file-descriptor

(注意:这是关于如何刷新write()的问题。这是的另一端,可以这么说。)< / p>

是否可以清空一个文件描述符,其中包含要在其中读取的数据而不必须read()?您可能对数据不感兴趣,因此阅读它们会浪费您可能更好地使用的空间和周期。

如果在POSIX中无法实现,那么任何操作系统都有任何不可移植的方法吗?

更新:请注意,我说的是文件描述符不是信息流。

8 个答案:

答案 0 :(得分:7)

如果您正在处理 tty ,请查看tcflush()

#include <termios.h>
int tcflush(int fildes, int queue_selector);
  

成功完成后,tcflush()   丢弃写入对象的数据   fildes提到的(一个打开的文件   与终端关联的描述符)   但未传输或收到数据   但不读,取决于价值   queue_selector [...]

http://opengroup.org/onlinepubs/007908775/xsh/tcflush.html

答案 1 :(得分:3)

对于POSIX,请使用lseek(2)lseek64(3)提前寻找。对于Windows,请使用SetFilePointer()SetFilePointerEx()

答案 2 :(得分:2)

Streams有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

答案 3 :(得分:1)

read()和flush()都不是标准C或C ++的一部分,但当然没有一个标准函数支持刷新输入流。我猜这反映了底层操作系统中没有的东西。避免完全阅读某些内容的常用方法是使用某种seek()函数跳过它。

答案 4 :(得分:1)

如果您知道要跳过的字节数,则可以为POSIX系统执行lseek(fd, n, SEEK_CUR);。对于fseek()个对象,也有FILE *个。在POSIX中,我认为您可以安全地搜索文件末尾,我们的想法是,如果以后写入更多数据,以便使数据超过lseek()设置的位置,您将能够阅读更多内容数据现在。

答案 5 :(得分:0)

根据this,POSIX系统将在fflush(stream);上执行此操作。

  

对于打开读取的流,如果文件尚未处于EOF,并且该文件是能够搜索的文件,则应调整底层打开文件描述的文件偏移量,以便对打开的文件描述进行下一个操作处理读取或写入正在刷新的流的最后一个字节后的字节。

答案 6 :(得分:0)

Linux 2.6.17或更高版本,GNU C库版本2.5或更高版本包含splice()系统调用,可用于将数据从一个文件描述符发送到另一个,而无需将其复制到用户空间。这可以通过简单地将源文件描述符中的/dev/nullsplice数据打开到/dev/null文件描述符中来丢弃数据。

答案 7 :(得分:0)

BSD引入了fpurge(),Solaris和glibc引入了__fpurge()
来自man page

#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及更高版本中。

如果您正在使用文件描述符,则可能可以先get a FILE* from the descriptor

int fd;
/* ... */
FILE* fp = fdopen(fd, "r");
/* ... */
__fpurge(fp);