使用C中的读取系统调用在缓冲区中读取可变大小的数据

Posted

技术标签:

【中文标题】使用C中的读取系统调用在缓冲区中读取可变大小的数据【英文标题】:Reading data of variable size in buffer using read system call in C 【发布时间】:2013-02-10 17:48:50 【问题描述】:

我有一个应用程序将数据(控制数据、访问信息等)写入父进程的管道一端。在子进程中,我想按原样读取该数据。

父进程在许多位置执行许多 write() 操作。为了将数据读入缓冲区,我们需要指定数据的长度

read(int fd, buffer, len).

我的问题是,父进程每次都会写入可变大小的数据。那么子进程是如何知道数据长度的呢。

我尝试读取单个字符并将其添加到 buff 中,

char ch;
int n = 0;
while(n >= 0)

    n = read(int fd, ch, 1);
    *buff = ch; buff++;

不过好像没办法

请告诉我如何在子进程中读取可变大小的数据?

【问题讨论】:

【参考方案1】:

嘿,你问了最古老的问题之一。多年来已经开发了许多答案......

写入按行组织的格式化数据,然后一次读取一行并解析尽可能多的数据 写入二进制数据,但先写入记录类型 如上,但在两个级别中,使用二进制数据,包装在带有类型字段的记录中,并且所有这些都以记录长度字开头。这使您可以分层构建读取器,较低的 I/O 层可以轻松读取记录并将其长度返回给负责应用特定逻辑的较高层。 按行写入格式化数据,但使用前导标识符标识“记录类型” 创建一种语言并为其编写解析器;解析器可能会逐字节读取输入 将数据整理为XML 将数据组织为YAML 将数据组织为JSON

所有这些技术都有一个共同点:读者必须已经知道编码类型,并且必须使用程序逻辑准备好根据其结构有条件地读取数据。当然,已经编写了可以读取 XML、YAML 和 JSON 的库。

【讨论】:

【参考方案2】:

您需要将格式化的数据放入管道中,这些数据可以在读取端进行解码。也就是说,您必须指定格式/协议才能理解输出的数据。您可以指定长度,或使用以 \n\0 字符结尾的行,无论您的数据如何。

【讨论】:

【参考方案3】:

两种最常见和最简单的方法是先以固定大小写入长度,或者使用特殊的记录终止符来告知记录已结束。

【讨论】:

以上是关于使用C中的读取系统调用在缓冲区中读取可变大小的数据的主要内容,如果未能解决你的问题,请参考以下文章

关于java的io读写,缓冲区是如何提高读写效率的???

为啥 boost::asio::read 缓冲区数据大小小于读取大小?

如何在 C 代码中动态更改/伪造“文件大小”

C语言 fread 函数

C中的管道,用于读取标准输入的缓冲区

bufferedinputstream的使用