你如何有效地实现尾部?

pru*_*nat 13 c unix linux tail

在*NIX中实现tail的有效方法是什么?我提出(写)两个简单的解决方案,都使用一种循环缓冲区将线加载到圆形结构(数组|双向链接循环列表 - 为了好玩).我在busybox中看到了部分较旧的实现,从我的理解,他们使用fseek找到EOF,然后"向后"阅读东西.那里有更清洁,更快的东西吗?我在面试时被问到这个问题并且提问者看起来并不满意.先感谢您.

aka*_*ppa 15

我不认为有一些解决方案不同于"在读取数据时保留最新的N行"或"从最后开始并向后移动直到您读取第N行".

关键是你要根据上下文使用一个或另一个.

当tail访问随机访问文件时,或者当数据足够小以便放入内存时,"走到最后并向后"会更好.在这种情况下,运行时最小化,因为您扫描必须输出的数据(因此,它是"最佳")

当尾部通过管道或数据量巨大时,您的解决方案(保留N条最新线路)会更好.在这种情况下,另一种解决方案浪费了太多内存,因此它不实用,并且在源比尾部慢(这是可能的)扫描所有文件并不重要.


thu*_*eys 7

从文件末尾向后读取,直到N读取换行符或到达文件的开头.

然后打印刚读过的内容.

我不认为这里需要任何花哨的数据结构.

如果您有兴趣,这是尾部的源代码.


Ber*_*ann 6

首先用于fseek查找文件结尾然后减去512并返回fseek到该偏移量,然后从那里向前读取到结束.计算换行次数,因为如果数量太少,则必须使用1024的减去偏移量进行相同的操作...但在99%的情况下,512就足够了.

(1)避免向前读取整个文件和(2)这可能比从末尾向后读取更有效的原因是向前读取通常更快.

  • 并在每次失败时将偏移量加倍。 (2认同)