如何从需要搜索的stdin管道数据中有效地读取

时间:2012-05-07 11:15:08

标签: c file memory stdin

我正在寻找在C编程中从stdin管道读取数据的最佳方法。

问题:我需要寻找这些数据,即我需要在读取同一流的 end 处的一些数据后从流的 start 读取数据

小用例:gunzip -c 4GbDataFile.gz | myprogram

另一个:

  1. 在本地主持人上:nc -l -p 1234 | myprogram
  2. 在远程主持人上:gunzip -c 4GbDataFile.gz | nc -q 0 theotherhost 1234
  3. 我知道从fifo读取只能进行一次。所以,目前:

    • 从<{1}} > 并从此分配的内存中工作。

    它很丑,但它确实有效。一个明显的问题是,如果有人向我的应用程序发送了一个巨大的(或连续的)流,我将以一个大的分配内存块结束,否则我将耗尽内存。 (想想8Gb文件)

    我接下来的想法:

    • 我设置了该内存块的大小限制(可能是用户定义的)。一旦我从stdin中读取了这么多数据:
      1. 我要么停在这里:&#34; Errr。记忆犹新,bazinga。算了。&#34; 风格。
      2. 我开始转储我正在阅读的到文件,并在读取所有数据后从此文件开始工作。

    但那么,有什么意义呢?我无法找到我正在阅读的数据的来源。如果这是一个本地8Gb文件,我将把它转储到同一系统上的另一个8Gb文件。

    所以,我的问题是:

      

    当您需要在stdin管道中来回搜索时,如何有效地从<{1}}管道中读取很多数据?

    提前感谢您的回答。

    编辑:

    我的程序需要在给定文件中的某处(取决于文件格式)读取元数据,以便可能在流的末尾。然后它可以在流的开头读回其他数据,然后在另一个地方读回等等。简而言之:它需要访问数据的任何字节。

    一个例子是在开始从stdin开始读取之前,在不知道文件格式的情况下读取存档文件的数据:我需要检查存档元数据,查找存档文件名称和偏移等。

    因此,我将制作stdin内容的本地副本并从中进行操作。感谢大家的投入;)

3 个答案:

答案 0 :(得分:1)

您需要明确要求。如果您需要搜索(),那么显然您无法从 stdin 获取输入。如果您需要 seek(),那么您应该将输入文件名作为参数。

答案 1 :(得分:0)

4GbDataFile中的数据结构不适合您想要做的事情。创造性思考。不要把你的程序搞砸到它甚至不应该尝试的东西。尝试修改生成它的输入格式,这样就不需要寻找4 GB。

如果你就像锤击一样:4GB的内核内存相当昂贵。相反,将从stdin读取的数据保存在文件中,然后打开文件(或mmap)并寻找你内心的内容。

答案 2 :(得分:0)

我认为你应该阅读臭名昭着的Useless Use of Cat Award

TL; DR:将cat 4gbfile | yourprogram更改为yourprogram < 4gbfile

如果您真的坚持使用管道中的数据,则必须在启动时将其存储在临时文件中,然后使用{{1替换文件描述符0和临时文件的fd副本}}