Linux tail -n的功能是如何实现的?
如果文件非常大,如何快速的取到文件的最后n行数据呢?
使用strace 命令跟踪下,发现如下的输出:
strace tail -1000 test.log 2>&1 | grep lseek
lseek(3, 0, SEEK_CUR) = 0
lseek(3, 0, SEEK_END) = 52876697
lseek(3, 52871168, SEEK_SET) = 52871168
lseek(3, 52862976, SEEK_SET) = 52862976
lseek(3, 52854784, SEEK_SET) = 52854784
...
- 使用SEEK_END找到文件的大小(为52876697)
- 然后使用SEEK_SET定位到文件的最后一个page,从上面这个case看,page大小是8192,最后一个page没满8192字节,seek到52876697 - 52876697 % 8192 == 52871168这个position
- 读取这一个page的所有数据,统计总共出现多少个换行
- 如果里面的行数不到n,再往前seek一个page(52871168-8192 == 52862976),读取数据,统计行数。
- 循环步骤4,直到取到n行数据。
- 顺序读取数据,输出n行数据。