查找有多少字节可供从 FILE* 或文件描述符中读取

发布于 2024-10-26 00:05:43 字数 455 浏览 6 评论 0原文

给定一个 FILE* 或文件描述符,是否有标准方法来判断有多少字节可供读取?

以来,我无法使用 s=ftell(f),fseek(f,0,SEEK_END),e=ftell(f),fseek(f,s,SEEK_SET),es FILE* 只是包装我从 pipe(2)< 获得的文件描述符/code>,当我尝试时,我得到了 ESPIPE

我正在考虑使用 select(2) 和零超时来告诉我至少有一个字节可供读取,然后一次读取一个字节,直到 select(2 ) 让我停下来。但这看起来有点笨重和缓慢。

有更好的方法吗?

Given a FILE* or a file descriptor, is there a standard way to tell how many bytes are ready to be read?

I can't use s=ftell(f),fseek(f,0,SEEK_END),e=ftell(f),fseek(f,s,SEEK_SET),e-s since the FILE* is just wrapping a file descriptor I got from pipe(2), and I get ESPIPE when I try that.

I was thinking of using select(2) with a zero timeout to tell that I have at least one byte ready to be read, and then reading a byte at a time until the select(2) told me to stop. This seems kinda clunky and slow though .

Is there a better way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

巾帼英雄 2024-11-02 00:05:43

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

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

read can return fewer bytes than you asked for, and must do so if data is available, but it would need to block in order to fill the buffer.

So the usual thing is to use select to detect readable, then read whatever your favoured buffer size is. Alternatively, set O_NONBLOCK using fcntl, and check for -1 return value and errno EAGAIN.

不及他 2024-11-02 00:05:43

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

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

If you're only looking for something more efficient that 1 byte reads, and not the size of the available data on the FIFO, then you can:

  1. Set the file descriptor to non blocking mode.
  2. Use select to know when data is available
  3. Call read with a large buffer. It might return less than you requested (check the return code), or it might return -1 with EAGAIN or EWOULDBLOCK to indicate you should go back to calling select (no data is availabe)
落花随流水 2024-11-02 00:05:43

它没有受到任何现代标准的祝福,但执行此操作的常见传统 unix 方法是使用 ioctl(fd, FIONREAD, &n); 请参阅此问题的答案:

在不调用 read() 的情况下确定管道的大小

It's not blessed by any modern standards, but a common traditional unix way to do this is with ioctl(fd, FIONREAD, &n); See the answers to this question:

Determine the size of a pipe without calling read()

山人契 2024-11-02 00:05:43

扩展 R 给出的答案..

一个大型的现实世界 软件框架 使用 ioctl 来找出像这样的字节(折扣错误检查):

FreeBSD、Linux 和 Solaris (来源):

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

IRIX (来源):

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

Windows (来源):

long nbytes;
ioctlsocket(fd, FIONREAD, &nbytes);

Extending on the answer given by R..

A large real-world software framework uses ioctl to find out the number of bytes like this (discounting error checks):

FreeBSD, Linux, and Solaris (source):

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

IRIX (source):

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

Windows (source):

long nbytes;
ioctlsocket(fd, FIONREAD, &nbytes);
罪歌 2024-11-02 00:05:43

多伊。 fstat(2)。我之前浏览过它,发现它不适用于 FILE*(这就是为什么我回到了 fseek 反模式),但没有考虑依靠文件描述符。

doy. fstat(2). I glanced at it earlier, and saw it wouldn't work on FILE*, (which is why I fell back to the fseek anti-pattern), but didn't think to fall back on the file descriptor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文