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

我需要一个称为SizeOfPipe()的函数,它应该返回一个pipe道的大小 – 我只想知道pipe道中有多less数据,而不是实际从pipe道本身读取数据。

我认为下面的代码将工作

fseek (pPipe, 0 , SEEK_END); *pBytes = ftell (pPipe); rewind (pPipe); 

但是fseek dosent在文件描述符上工作。 另一个select是读取pipe道然后写回数据,但是如果可能的话,想避免这种情况,有什么build议吗?

Solutions Collecting From Web of "在不调用read()的情况下确定pipe道的大小"

取决于你的unix的实现ioctl / FIONREAD可能会做的伎俩

 err = ioctl(pipedesc,FIONREAD,&bytesAvailable);

除非此函数返回“无效参数”(或任何其他错误)的错误代码,否则bytesAvailable包含此时解除读取操作可用的数据量。

不幸的是,系统不能总是知道管道的大小 – 例如,如果你正在将一个长期运行的进程传送到另一个命令中,源进程可能还没有完成运行。 在这种情况下,即使在理论上也没有办法知道有多少数据会从中产生。

如果你想知道当前可用的数据量是否可能读出管道,但这取决于操作系统缓冲和其他难以控制的因素。 这里最常见的方法就是继续阅读,直到没有什么可留下来(如果你没有得到EOF,那么源程序还没有完成)。 不过,我不认为这是你在找什么。

所以恐怕没有一般的解决办法。

某些UNIX实现在调用fstat()之后返回可以在st_size字段中读取的字节数,但这不是可移植的。

通常不可能知道只能从管道手柄中读取的数据量。 数据可能通过网络传入,或者由另一个进程动态生成。 如果您需要知道前面的情况,您应该安排将信息通过管道或带外传送给您 – 通过管道另一端的任何过程。

没有通用的,便携的方式来告诉管道中有多少数据可用,而没有读取它。 至少不在POSIX规范下。

管道是不可搜索的,也不可能将数据放回到管道的读取端。

不过,特定于平台的技巧也许是可能的。 如果你的问题是针对特定平台的,编辑你的问题可能会提高你获得工作答案的机会。

几乎没有必要知道管道中有多少个字节:也许你只是想在管道上做一个非阻塞的read(),也就是说, 检查是否有任何字节准备好,如果是,读取它们,但是不要停下来等待管道准备就绪。

你可以分两步做。 首先,使用select()系统调用来确定数据是否可用。 一个例子是在这里: http : //www.developerweb.net/forum/showthread.php?t=2933

其次,如果select指示数据可用,则调用read()一次,并且只调用一次,块大小较大。 它只能读取尽可能多的字节,或者最多可以读取块的大小,以较小者为准。 如果select()返回true,则read()将始终立即返回。

我不认为这是可能的,是不是管道两端(在一个方向)提供进程间通信的重点。 如果我在这个断言中是正确的,那么发送可能还没有完成将数据推入管道 – 所以不可能确定长度。

你在使用什么平台?

我不认为这是可能的。 管道呈现面向流的协议,而不是面向分组的。 IOW,如果你写了一个管道两次,一次是250个字节,一次是520个字节,那么在一次读取请求中就没有办法知道从另一个端口得到多少个字节。 你可以得到256,256,然后剩下的。

如果你需要在一个管道上施加数据包,你需要自己写一个预定的(或定界的)字节数作为数据包的长度,然后是其他数据包。 使用select()来查找是否有数据要读取,使用read()来获得合理大小的缓冲区。 当你有你的缓冲区时,你有责任确定数据包边界。

如果你想知道预计到达的数据量,你可以在管道发送的每个msg的开始处写上msg的大小。 因此,在每个msg的开始处写入例如4个字节的数据长度,然后只读取前4个字节。

没有可移植的方式来判断来自管道的数据量。 你唯一能做的就是读取和处理数据。

为此,你可以使用类似循环缓冲区的东西

你可以把它包装在缓冲的对象中,可以被重新打包。 这只适用于少量的数据。

在C中做这个的一个方法是定义stuct并包装所有在管道上运行的函数。

在Windows上,你总是可以使用PeekNamedPipe ,但是我怀疑这就是你想要做的。