你将如何有效地实现尾巴?

在NIX中实现tail的有效方法是什么? 我写了两个简单的解决scheme,都使用循环缓冲区来将行加载到循环结构中(为了好玩)。 我已经看到在busybox中的一些旧的实现,并从我的理解,他们使用fseek来findEOF,然后“东倒西歪”的东西。 那里有更干净更快的东西吗? 我在面试时被问到了这个问题,提问者看起来并不满意。 先谢谢你。

Solutions Collecting From Web of "你将如何有效地实现尾巴?"

我不认为有解决方案不同于“在读取数据前保持最新的N行”或“从头开始,向后走,直到读第N行”。

重点是你会根据上下文使用一个或另一个。

当尾部访问一个随机访问文件时,或者当数据足够小,可以放到内存中时,“走到头,倒退走”更好。 在这种情况下,运行时间被最小化,因为您扫描必须输出的数据(所以它是“最佳”的)

当你的解决方案(保持最新的N条线)在尾部输入流水线或数据量很大时更好。 在这种情况下,另一个解决方案浪费太多的内存,所以这是不实际的,并且在源比尾更慢(这很可能)的情况下扫描所有文件并不重要。

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

然后打印刚刚阅读的内容。

我不认为这里需要任何奇特的数据结构。

如果你感兴趣, 这里是尾巴的源代码 。

首先使用fseek找到文件结束,然后减去512和fseek到该偏移量,然后从那里读取结束。 计算换行符的数量,因为如果太少,您将不得不做相同的减法偏移量1024 但在99%的情况下,512将是足够的。

(1)避免了阅读整个文件, (2)为什么这可能比从头阅读的效率更高的原因是阅读前进通常更快。

/ *This example implements the option n of tail command.*/

 #define _FILE_OFFSET_BITS 64 #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <getopt.h> #define BUFF_SIZE 4096 FILE *openFile(const char *filePath) { FILE *file; file= fopen(filePath, "r"); if(file == NULL) { fprintf(stderr,"Error opening file: %s\n",filePath); exit(errno); } return(file); } void printLine(FILE *file, off_t startline) { int fd; fd= fileno(file); int nread; char buffer[BUFF_SIZE]; lseek(fd,(startline + 1),SEEK_SET); while((nread= read(fd,buffer,BUFF_SIZE)) > 0) { write(STDOUT_FILENO, buffer, nread); } } void walkFile(FILE *file, long nlines) { off_t fposition; fseek(file,0,SEEK_END); fposition= ftell(file); off_t index= fposition; off_t end= fposition; long countlines= 0; char cbyte; for(index; index >= 0; index --) { cbyte= fgetc(file); if (cbyte == '\n' && (end - index) > 1) { countlines ++; if(countlines == nlines) { break; } } fposition--; fseek(file,fposition,SEEK_SET); } printLine(file, fposition); fclose(file); } int main(int argc, char *argv[]) { FILE *file; file= openFile(argv[2]); walkFile(file, atol(argv[1])); return 0; } /*Note: take in mind that i not wrote code to parse input options and arguments, neither code to check if the lines number argument is really a number.*/