- 论坛徽章:
- 4
|
本帖最后由 linux_c_py_php 于 2013-05-04 12:48 编辑
写了一个优化的, 性能比hbmhalley的好一点, 思路都一样, 主要是减少了fgetc调用, 使用4KB一读优化磁盘读效率, 另外查找使用向前查找可以避免最后的回滚逻辑, 代码丑莫见怪:- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- /* linux only */
- int tail_lines(const char *file, int nline)
- {
- if (!nline)
- return 0;
- int fd = open(file, O_RDONLY);
- if (fd == -1)
- return -1;
- off_t size = lseek(fd, 0, SEEK_END);
-
- int cnt = 0;
- char buf[4096]; /*faster with 4kb per read*/
- off_t last = size;
- off_t respos = 0;
- while (last) {
- off_t cur = lseek(fd, last - sizeof(buf), SEEK_SET);
- off_t toread;
- if (cur == (off_t)-1) {
- cur = lseek(fd, 0, SEEK_SET);
- toread = last;
- } else
- toread = sizeof(buf);
- int nread = read(fd, buf, toread);
- if (nread != toread)
- return -1; /*never happen*/
-
- int i;
- for (i = nread - 1; i >=0; --i) {
- if (buf[i] == '\n') {
- cnt++;
- if (cnt == nline + 1) {
- respos = cur + i + 1;
- cnt--;
- goto end;
- }
- }
- }
- if (!cur) {
- cnt++;
- break;
- }
- last = cur;
- }
- end:
- lseek(fd, respos, SEEK_SET);
- while (1) {
- int n = read(fd, buf, sizeof(buf));
- if (n > 0)
- write(1, buf, n);
- else
- break;
- }
- close(fd);
- return --cnt;
- }
- int main(int argc, char *const argv[])
- {
- if (argc < 3)
- return -1;
- int cnt = tail_lines(argv[1], atoi(argv[2]));
- printf("line_count=%d\n", cnt);
- return 0;
- }
复制代码 |
|