Linux tail 命令实现 (C语言)

设计要求

  • 编写一个程序,输出一个文件的最后几行。这个程序运行后要能跳到文件末尾附近,然后一直读取指定的数据行数,并全部打印出来。运行程序的命令是 tail -n file ,其中参数 n 是指从文件末尾数起要打印的行数,默认的 n10

设计思路

  • 利用 lseek() 系统调用移动文件指针的位置,先移动到文件末尾,然后从下往上一步一步的移动,每次读取文件的一个字符,根据 \n 的个数进行行数计算
  • 为了防止文件过大引起的缓存不足,使用 零拷贝sendfile() 系统调用,直接将文件内容重定向到标准输出,大大提高了效率

源代码

#include 
#include 
#include 
#include 
#include 
#include 

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,C,c语言,linux,开发语言)