如何在便携式C语言中从管道读取时向前查找

10

由于fseek()在管道上不起作用,因此模拟向前寻找的方法有哪些?幼稚的方法是使用fread()并且将读入内存缓冲区的内容丢弃。为了避免巨大的寻求而不必使用巨大的缓冲区,您可以一遍又一遍地使用相同的缓冲区,最后只使用缓冲区的一部分进行读取。

但这是唯一的方法吗?是否还有其他方式可以避免缓冲区和潜在的多次读取?

2个回答

6

在管道上进行寻求操作并没有意义,因为输入是动态产生的(而不是存储在磁盘上)。内核系统调用lseek对于管道没有实现。

此外,请记住,管道本质上是一个大小有限且固定的生产者-消费者缓冲区。当它满了时,生产者被暂停,直到消费者读取最早的数据。


如果对缓冲区和多个read()调用跳过数据存在疑虑,也许最好根本不使用管道。让源将数据写入磁盘文件,然后管道的接收端可以使用lseek()系列调用。 - wallyk
当然,但有时动态生成的输出是以已知格式呈现的。 - hippietrail
@wallyk:我过去使用管道的一些原因包括处理来自巨大压缩存档的XML以及在互联网上传输时即时处理XML。有时您所需的仅是整个数据的一部分,有时您没有磁盘空间来存储所有这样未经压缩的存档。 - hippietrail
1
@hippietrail:这里有一个在Linux中实现可寻址管道的尝试,你可能会觉得很有趣:http://lkml.indiana.edu/hypermail/linux/kernel/0411.3/0739.html - Blagovest Buyukliev
@Blagovest Buyukliev:唉,那个线程没有得出解决方案。 - wallyk
@hippietrail:那么唯一合理的解决方案就是重新实现管道的源端,以便符合您的需求。 - wallyk

5

是的,这是唯一的方法。我会使用大约1k-8k左右的缓冲区。如果太小,读取系统调用的开销就会变得很大,而如果太大,你会从缓存中清除有用的数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接