查找准备从FILE *或文件描述符中读取的字节数

时间:2011-03-23 17:23:44

标签: c pipe file-descriptor

给定FILE*或文件描述符,有没有一种标准方法可以告诉你有多少字节可以读取?

我无法使用s=ftell(f),fseek(f,0,SEEK_END),e=ftell(f),fseek(f,s,SEEK_SET),e-s,因为FILE*只是包装了我从pipe(2)获取的文件描述符,当我尝试时,我得到ESPIPE

我正在考虑使用select(2)以零超时来告诉我至少有一个字节准备好被读取,然后一次读取一个字节,直到select(2)告诉我停止。这看起来有点笨拙而且很慢。

有更好的方法吗?

5 个答案:

答案 0 :(得分:6)

read可以返回比你要求的更少的字节,如果数据可用,则必须这样做,但是为了填充缓冲区,它需要阻塞。

通常情况下使用select来检测可读性,然后读取您喜欢的缓冲区大小。或者,使用fcntl设置O_NONBLOCK,并检查-1返回值和errno EAGAIN。

答案 1 :(得分:4)

没有任何现代标准的祝福,但是常见的传统unix方法是使用ioctl(fd, FIONREAD, &n);查看此问题的答案:

Determine the size of a pipe without calling read()

答案 2 :(得分:3)

如果你只是寻找1字节读取的更有效的东西,而不是FIFO上可用数据的大小,那么你可以:

  1. 将文件描述符设置为非阻塞模式。
  2. 使用select了解数据何时可用
  3. 使用大缓冲区调用read。它可能返回的次数少于您的请求(检查返回代码),或者它可能会返回-1,EAGAINEWOULDBLOCK表示您应该返回调用{{1 (没有数据可用)

答案 3 :(得分:1)

扩展了R给出的答案。

一个大型的现实世界software framework使用ioctl来查找这样的字节数(折扣错误检查):

FreeBSD,Linux和Solaris source):

F

IRIX source):

int nbytes;
ioctl(fd, FIONREAD, &nbytes);

Windows source):

size_t nbytes;
ioctl(fd, FIONREAD, &nbytes);

答案 4 :(得分:0)

DOY。 fstat(2)。我之前看了一眼,看到它在FILE*上不起作用(这就是我回到fseek反模式的原因),但是没想到会回到文件上描述符。