您的位置:首页 > 其它

Pro_4_UNIX下高效readline函数的实现_2016_08_10

2016-08-11 07:35 519 查看
readline.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

/*
* 抄自《UNIX网络编程:卷1》, 稍作修改。
* 仅仅用于学习目的。学无止境,进步每一天。
*
* slickedit编辑。
*
* 254008829@qq.com
*
*/

#define MAXLINE 1024

static int read_cnt;
static char *read_ptr;
static char read_buf[MAXLINE];

static ssize_t
my_read(int fd, char *ptr)
{
if (read_cnt <= 0)
{
again:
if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0)
{
if (errno == EINTR)
goto again;
return -1;
}
else if (read_cnt == 0)
{
return 0;
}
read_ptr = read_buf;
}

read_cnt--;
*ptr = *read_ptr++;
return 1;
}

ssize_t
my_readline(int fd, void *vptr, size_t maxline)
{
ssize_t n, rc;
char c, *ptr;

ptr = vptr;
for (n=1; n<maxline; n++)
{
if ( (rc = my_read(fd, &c)) == 1)
{
*ptr++ = c;
if (c == '\n')
break;
}
else if (rc == 0)
{
*ptr = 0;
return n -1;
}
else
return -1;
}

*ptr = 0;
return n;
}

ssize_t
readbufline(char **vptr)
{
if (read_cnt > 0)
*vptr = read_ptr;
return read_cnt;
}

// 这个宏是为了调用其中的func,类似包裹函数。只有当所调用的函数(func), 以返回小于0的数字为错误值的时候才适用。
#define FUNC_RET(func, val) \
do { \
int rv; \
if ( (rv=func) < 0) { \
printf("LINE = %d, error str: %s\n", __LINE__, strerror(errno)); \
perror("FUNC_RET"); \
exit(-1); \
} \
val = rv; \
} while (0);

/* 自己实现的main函数 */
int main(int argc, char **argv)
{
if (argc != 2) {
printf("Usage: %s filename\n", argv[0]);
exit(0);
}

int filefd, ret;
char readbuf[MAXLINE] = {0};
FUNC_RET(open(argv[1], O_RDONLY), filefd);
FUNC_RET(my_readline(filefd, readbuf, sizeof(readbuf)), ret);
printf("I get a line @\"%s\": %s\n", argv[1], readbuf);
FUNC_RET(close(filefd), ret);

exit(0);
}

/*
编译readline.c生成raadline可执行文件,然后执行命令:./readline readline.c
结果为: I get a line @"readline.c": #include <stdio.h>
*/


> 上述my_read, my_readline函数用到了文件自带的缓冲read_buf。my_read函数一次系统调用read将读到数据放到read_buf中,my_readline函数从read_buf里面取读出相应的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: