c - 如何处理基于 C 的应用程序内部的数据流?

标签 c stream io buffer bzip2

我正在从 bzip2 中提取数据C 应用程序中的流。当数据 block 从解压缩器中出来时,它们可以写入 stdout :

fwrite(buffer, 1, length, stdout);

这很好用。当它发送到 stdout 时,我得到了所有数据.

而不是写入 stdout ,我想在内部以单行 block 的形式处理此语句的输出:一个以换行符结尾的字符串 \n .

我是否将解压缩器流的输出写入另一个缓冲区,一次一个字符,直到遇到换行符,然后调用每行处理函数?这很慢吗?有没有更聪明的方法?感谢您的建议。

编辑

感谢您的建议。每次我通过输出缓冲区的数据时,我最终创建了一对缓冲区,用于在短行缓冲区的开头存储剩余部分(输出缓冲区末尾的“ stub ”)。

我逐个字符地遍历输出缓冲区,一次处理一个换行符的数据量。无换行余数被分配和分配,并复制到下一个流的行缓冲区。好像realloc比重复malloc-free便宜声明。

这是我想出的代码:

char bzBuf[BZBUFMAXLEN];
BZFILE *bzFp;
int bzError, bzNBuf;
char bzLineBuf[BZLINEBUFMAXLEN];
char *bzBufRemainder = NULL;
int bzBufPosition, bzLineBufPosition;

bzFp = BZ2_bzReadOpen(&bzError, *fp, 0, 0, NULL, 0); /* http://www.bzip.org/1.0.5/bzip2-manual-1.0.5.html#bzcompress-init */ 

if (bzError != BZ_OK) {
    BZ2_bzReadClose(&bzError, bzFp);   
    fprintf(stderr, "\n\t[gchr2] - Error: Bzip2 data could not be retrieved\n\n");
    return -1;          
}

bzError = BZ_OK;
bzLineBufPosition = 0;
while (bzError == BZ_OK) {

    bzNBuf = BZ2_bzRead(&bzError, bzFp, bzBuf, sizeof(bzBuf));

    if (bzError == BZ_OK || bzError == BZ_STREAM_END) {
        if (bzBufRemainder != NULL) {
            /* fprintf(stderr, "copying bzBufRemainder to bzLineBuf...\n"); */
            strncpy(bzLineBuf, bzBufRemainder, strlen(bzBufRemainder)); /* leave out \0 */
            bzLineBufPosition = strlen(bzBufRemainder);
        }

        for (bzBufPosition = 0; bzBufPosition < bzNBuf; bzBufPosition++) {
            bzLineBuf[bzLineBufPosition++] = bzBuf[bzBufPosition];
            if (bzBuf[bzBufPosition] == '\n') {
                bzLineBuf[bzLineBufPosition] = '\0'; /* terminate bzLineBuf */

                /* process the line buffer, e.g. print it out or transform it, etc. */
                fprintf(stdout, "%s", bzLineBuf);

                bzLineBufPosition = 0; /* reset line buffer position */
            }
            else if (bzBufPosition == (bzNBuf - 1)) {
                bzLineBuf[bzLineBufPosition] = '\0';
                if (bzBufRemainder != NULL)
                    bzBufRemainder = (char *)realloc(bzBufRemainder, bzLineBufPosition);
                else
                    bzBufRemainder = (char *)malloc(bzLineBufPosition);
                strncpy(bzBufRemainder, bzLineBuf, bzLineBufPosition);
            }
        }
    }
}

if (bzError != BZ_STREAM_END) {
    BZ2_bzReadClose(&bzError, bzFp);
    fprintf(stderr, "\n\t[gchr2] - Error: Bzip2 data could not be uncompressed\n\n");
    return -1;  
} else {   
    BZ2_bzReadGetUnused(&bzError, bzFp, 0, 0);
    BZ2_bzReadClose(&bzError, bzFp);
}

free(bzBufRemainder);
bzBufRemainder = NULL;

非常感谢大家的帮助。这工作得很好。

最佳答案

我不认为有更聪明的方法(除了找到一个已经为您做这件事的自动机库)。为“最后一行”缓冲区分配适当的大小时要小心:如果它不能处理任意长度并且输入来自第三方可访问的内容,就会成为安全风险。

关于c - 如何处理基于 C 的应用程序内部的数据流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3923014/

相关文章:

node.js - NodeJS 从 https 流写入二进制文件

javascript - 如何在 JavaScript 中创建、打开、保存和关闭文件或目录?

linux - 从 crontab 运行时,Perl 中的 Carp 库在哪里打印日志

c++ - 在 C++ 程序中显示进程完成的百分比

c - Microsoft 编译器下 _rdrand_step 内在函数的可用性?

c - 在 PostgreSQL 中,如何根据 C 函数中的类型 Oid 来识别类型是复合类型?

从 C 中的数组更改变量中的字符串

c - SPOJ - 好斗的奶牛, "largest minimum distance"术语的含义是什么?

c# - 有效拆分以分隔符分隔的消息

java - java ObjectOutputStream方法的defaultWriteObject和writeObject之间的异同