Parsing 为分隔符分隔的块缓冲数据
有一个问题我想了很久,我希望有人能给我一个答案,让我安心 让我们假设我有一个输入流(如文件/套接字/管道),并希望解析传入的数据。让我们假设每个传入数据块都被一条换行线分割,就像大多数常见的internet协议一样。该应用程序也可以解析html、xml或任何其他智能数据结构。关键是数据被分隔符而不是固定长度分割成逻辑块。如何缓冲数据以等待分隔符出现 答案似乎很简单:只要有一个足够大的字节/字符数组来容纳整个内容 但是如果分隔符出现在缓冲区已满之后呢?这实际上是一个关于如何在固定大小的块中适应动态数据块的问题。我真的只能想到几个选择:Parsing 为分隔符分隔的块缓冲数据,parsing,buffer,delimiter,Parsing,Buffer,Delimiter,有一个问题我想了很久,我希望有人能给我一个答案,让我安心 让我们假设我有一个输入流(如文件/套接字/管道),并希望解析传入的数据。让我们假设每个传入数据块都被一条换行线分割,就像大多数常见的internet协议一样。该应用程序也可以解析html、xml或任何其他智能数据结构。关键是数据被分隔符而不是固定长度分割成逻辑块。如何缓冲数据以等待分隔符出现 答案似乎很简单:只要有一个足够大的字节/字符数组来容纳整个内容 但是如果分隔符出现在缓冲区已满之后呢?这实际上是一个关于如何在固定大小的块中适应动态
readLine()
stream方法提供了某种缓冲机制
有什么“最好的方法”来解决这个问题吗?还是总是有一个折衷的办法?我真的很感激关于这个主题的所有想法和想法,因为每当我需要编写某种类型的解析器时,这个问题一直困扰着我。选项(2)和(3)都不存在,因为在这两种情况下都会丢失数据。选项(4)一个巨大的固定大小的缓冲区并不能解决这个问题,因为不可能知道什么大小足够大?是所有物理内存+交换空间+已知世界中所有磁盘中可用的可用空间吗
调整缓冲区的大小看起来是最好的解决方案。假设realloc的大小是原来的两倍,然后继续写入。总是有可能出现一个特殊构造的流,比如DoS,试图破坏系统。我的第一个想法是将缓冲区的最大大小设置为任意大。但是,如果我们能够做到这一点,我们可以将因此,对我来说,调整缓冲区的大小似乎是最好的选择
为什么要等待开始处理 一般来说,备选方案4是合理的。然而,它不需要“假设”,而需要一个定义。您只需声明块小于8K,并用它来完成。这并不困难 此外,还有备选方案5:开始处理部分缓冲区。除非您设计了一个真正病态的协议,在数据块的最后发送关键数据,否则这种方法是有效的
HTML、XML、JSON/YAML等都可以增量解析。你不需要一个delimeter来进行有用的处理。通常有两种技术可以实现这一点 1) 我认为readline使用的是—如果缓冲区填满,则返回的数据末尾没有分隔符 2) 当缓冲区填充时,请记住它已填充,继续读取,直到获得分隔符并报告错误(或按缓冲区大小截断记录)