命令实现 (C语言)"/>
Linux tail 命令实现 (C语言)
设计要求
- 编写一个程序,输出一个文件的最后几行。这个程序运行后要能跳到文件末尾附近,然后一直读取指定的数据行数,并全部打印出来。运行程序的命令是
tail -n file
,其中参数n
是指从文件末尾数起要打印的行数,默认的n
为10
行
设计思路
- 利用
lseek()
系统调用移动文件指针的位置,先移动到文件末尾,然后从下往上一步一步的移动,每次读取文件的一个字符,根据\n
的个数进行行数计算 - 为了防止文件过大引起的缓存不足,使用
零拷贝
的sendfile()
系统调用,直接将文件内容重定向到标准输出,大大提高了效率
源代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/sendfile.h>int main(int argc, char* argv[]) {int fd, n = 10;if (argc == 2) {fd = open(argv[1], O_RDONLY); // 以只读方式打开文件}else if(argc == 3) {fd = open(argv[2], O_RDONLY);n = atoi(argv[1] + 1);}off_t size = lseek(fd, 0, SEEK_END); // 可以把文件指针移动到文件末尾, 返回值是文件首部到尾部的偏移量off_t offset = 0;char ch;while (lseek(fd, -1, SEEK_CUR) >= 0 && n > 0) {read(fd, &ch, 1); // read会让文件指针向后移动一位offset = lseek(fd, -1, SEEK_CUR);if (ch == '\n') --n;}if (n == 0) ++offset; // 跳过一个回车符sendfile(STDOUT_FILENO, fd, &offset, size - offset);close(fd);return 0;
}
测试结果
- 根据测试,结果同Linux的
tail
命令一致 foo.txt
内容如下hello world welcome to Linux
./mytail -3 foo.txt
结果welcome to Linuxroot@balabala#
更多推荐
Linux tail 命令实现 (C语言)
发布评论