使用klib的kseq.h进行缓冲的行读取,http://attractivechaos.github.io/klib/#Kseq%3A%20stream%20buffer%20and%20FASTA%2FQ%20parser
给的使用案例为
#include <zlib.h>
#include <stdio.h>
#include <stdlib.h>
#include "kseq.h"
KSTREAM_INIT(gzFile, gzread, 16384)
int main(int argc, char *argv[])
{
gzFile fp; //初始化gz文件
kstream_t *ks; //初始化流对象
kstring_t str = {0,0,0}; //初始化字符串结构
if (argc == 1) {
fprintf(stderr, "Usage: %s <in.txt>\n", argv[0]);
return 1;
}
fp = gzopen(argv[1], "r");
ks = ks_init(fp); //将fp赋值给流对象
while (ks_getuntil(ks, '\n', &str, 0) >= 0) //读取一行, 通过指针将内容传递给str
printf("%s\n", str.s);
ks_destroy(ks); //释放内存
gzclose(fp); //关闭文件
free(str.s); //释放内存
return 0;
}
KSTREAM_INIT
接受三个参数,文件类型,读取函数__read
,缓冲大小,其中读取函数对应的宏为__read(ks->f, ks->buf, __bufsize)
,也就是__read
的第一个参数是文件类型,第二个参数是字符串,第三个是缓冲大小。
kstream_t
结构如下,其中type_t
是KSTREAM_INIT
的第一个参数,这里就是gzFile
.
typedef struct __kstream_t {
unsigned char *buf;
int begin, end, is_eof;
type_t f;
} kstream_t
kstring_t
结构包括三个元素,分别是l,m,s.
typedef struct __kstring_t {
size_t l, m;
char *s;
} kstring_t
m
的用于重新动态的确定char *s
的内存大小
if (str->m - str->l < (size_t)(i - ks->begin + 1)) {
str->m = str->l + (i - ks->begin) + 1;
kroundup32(str->m);
str->s = (char*)realloc(str->s, str->m);
}
l
的作用是从将缓冲里内容复制到上一段未完段落字符串的末尾。
memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin)
s
就是最终的字符串。
ks_getuntil
的函数声明为
static inline int ks_getuntil(kstream_t *ks, int delimiter, kstring_t *str, int *dret)
接受四个输入,kstream_t
结构地址,分隔符,kstring_t
结构地址和返回元素大小。
如果没有zlib,可以用更加底层的open, read, closer
#include <fcntl.h> //定义了open
#include <unistd.h> //定义了 read, close
#include <stdio.h>
#include <stdlib.h>
#include "klib/kseq.h"
KSTREAM_INIT(int, read, 1000)
int main(int argc, char *argv[])
{
int fd; // file descriptor
kstream_t *ks; //初始化流对象
kstring_t str = {0,0,0}; //初始化字符串结构
if (argc == 1) {
fprintf(stderr, "Usage: %s <in.txt>\n", argv[0]);
return 1;
}
fd = open(argv[1], O_RDONLY);
ks = ks_init(fd); //将fp赋值给流对象
while (ks_getuntil(ks, '\n', &str, 0) >= 0) //读取一行, 通过指针将内容传递给str
printf("%s\n", str.s);
ks_destroy(ks); //释放内存
close(fd); //关闭文件
free(str.s); //释放内存
return 0;
}
推荐阅读:
https://attractivechaos.wordpress.com/2008/10/11/a-generic-buffered-stream-wrapper/