Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何高效地读取需要查找的标准DIN管道数据_C_File_Memory_Stdin - Fatal编程技术网

C 如何高效地读取需要查找的标准DIN管道数据

C 如何高效地读取需要查找的标准DIN管道数据,c,file,memory,stdin,C,File,Memory,Stdin,我正在寻找在C编程中从stdin管道读取数据的最佳方法 问题:我需要寻找这个数据,即我需要在读取同一个流末尾的一些数据后,从流的开头读取数据 小用例:gunzip-c4gbdatafile.gz|myprogram 另一个: 在本地主机上:nc-l-p1234 | myprogram 在远程主机上:gunzip-c4gbdatafile.gz | nc-q 0其他主机1234 我知道从fifo读取只能执行一次。因此,目前: 我从stdin把所有东西都读到内存中,并从分配的内存中工作 虽然很难

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

问题:我需要寻找这个数据,即我需要在读取同一个流末尾的一些数据后,从流的开头读取数据

小用例:
gunzip-c4gbdatafile.gz|myprogram

另一个:

  • 在本地主机上:
    nc-l-p1234 | myprogram
  • 在远程主机上:
    gunzip-c4gbdatafile.gz | nc-q 0其他主机1234
  • 我知道从fifo读取只能执行一次。因此,目前:

    • 我从
      stdin
      把所有东西都读到内存中,并从分配的内存中工作
    虽然很难看,但它很管用。一个明显的问题是,如果有人向我的应用程序发送一个巨大的(或连续的)流,我将以一个大的分配内存块结束,否则我将耗尽内存。(想想8Gb的文件)

    接下来我想:

    • 我设置了该内存块的大小限制(可能是用户定义的)。一旦我从stdin中读取了这么多数据:
    • 要么我就停在这里:“呃,记忆不足,巴辛加。算了吧。”风格
    • 要么我开始转储我正在读取的到一个文件,并在读取所有数据后从此文件开始工作
    但是,问题是什么?我找不到我正在阅读的数据的来源。如果这是一个本地8Gb文件,我将把它转储到同一系统上的另一个8Gb文件中

    所以,我的问题是:

    当您必须在
    stdin
    管道中来回搜索时,如何有效地读取
    stdin
    管道中的大量数据

    提前感谢您的回答

    编辑:


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

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


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

    您需要明确您的需求。如果需要seek(),那么显然不能从stdin获取输入。如果需要seek(),则应将输入文件名作为参数。

    4GB数据文件中的数据结构无法满足您的需要。创造性思考不要把你的程序硬塞进它甚至不应该尝试的东西里。尝试修复生成输入格式的位置,这样就不需要查找回4GB


    如果您确实喜欢锤击:4GB的内核内存非常昂贵。相反,将从stdin读取的数据保存在一个文件中,然后打开该文件(或mmap)并查找您的内容。

    我认为您应该阅读臭名昭著的

    TL;DR:将
    cat 4gbfile |您的程序
    更改为
    yourprogram<4gbfile


    如果您真的坚持让它处理来自管道的数据,那么您必须在启动时将其存储在一个临时文件中,然后使用
    dup2

    将文件描述符0替换为临时文件的fd副本。我提到过,目前,它的工作方式是将所有内容存储到内存中,并在此处执行工作。我想当使用临时文件时,它也会起作用。我知道我不能在
    fifo
    上寻找,我在寻找一个优雅的(比我咕噜咕噜)解决方法;)我想当使用临时文件时,它会起作用但是,当您只是复制文件内容时,为什么要这样做呢?你的程序是做什么的?我的程序需要读取给定文件中某个地方的元数据(取决于文件格式),因此可能在流的末尾。然后,它可以在流的开始处读回其他数据,然后在另一个地方等。简言之,它需要访问数据的任何字节。例如,在不知道文件格式的情况下读取存档文件的数据:我需要检查存档元数据,查找存档文件的名称和偏移量等。因此,如果您的程序处理文件,则将其视为文件,即从任何位置查找和读取。除了
    stdin
    不是普通文件,不是吗?我不能像往常一样去寻找或阅读它。这就是为什么我目前正在将从stdin读取的数据映射到内存(或者映射到文件,但是如果$user只是将本地文件映射到我的程序,我将复制该文件,而不是处理原始文件…)。如果$user向我发送了大量数据,我要寻找的是一种优雅的回退方式。ITYM
    myprogram<4GbDataFile
    。目前,
    cat 4GbDataFile>myprogram
    会覆盖您的程序二进制文件。当你用管道替换“>”时,你对cat的使用是无用的。谢谢,修复了打字错误,添加了更有用的cat用法。我无法修复输入格式,因为它可以是任何东西(我编辑了我的问题,并在最后添加了一个程序工作示例)。mmaping一个4GB文件不会导致核心内存块中出现4GB吗?将读取的数据保存到文件中并在其中查找可能更合适,但如果它是本地文件,则只是复制原始文件并处理副本,而不是原始文件……你不能既吃馅饼又吃馅饼。在管道上寻找是不可能的。如果你坚持这样做,你就必须把看不见的数据变成看不见的数据(通过保存副本)。当映射时,不要映射整个数据,只需映射从搜索偏移量计算出的要搜索到的块。好的,谢谢,我将制作一个副本并警告用户不要将巨大的本地文件管道化,并宁愿将它们作为fd,以避免复制内容。这就是我想要的:使用