Ich habe so etwas wie einen Schwanz gemacht, der die letzten n Zeilen einer Datei in Ruby anzeigt
Versuche nachzuahmen.
tail_simple.rb
file_path = ARGV[0]
row_limit = ARGV[1].to_i
buffer = []
File.foreach(file_path) do |line|
buffer << line
buffer.shift if buffer.size > row_limit
end
puts buffer
Zunächst aus dem Kommentarbereich des Originalartikels. Wenn Sie es mit Ruby machen, fühlt sich das gut an. Diese Funktion ist
Eine solche. Es ist überraschend schnell, wenn ich es versuche.
tail_buffered.rb
def reverse_chunks(file, size)
n = file.size / size
n -= 1 if file.size == n * size
len = file.size - n * size
until n < 0
file.seek(n * size)
yield file.read(len)
n -= 1
len = size
end
end
def offset_of_nth_chr_from_tail(file, count, target)
offset = 0
reverse_chunks(file, 1024*16) do |chunk|
chunk.size.times do |i|
chr = chunk[chunk.size - i - 1]
if chr == target || (offset == 0 && i == 0 && chr != target)
count -= 1
if count < 0
offset += i
return offset
end
end
end
offset += chunk.size
end
offset
end
def tail(fname, n_lines)
open(fname) do |file|
offset = offset_of_nth_chr_from_tail(file, n_lines, "\n")
file.seek(file.size - offset)
print file.read
end
end
tail(ARGV[0], ARGV[1].to_i)
Als nächstes schrieb ich einen Schwanz von Ruby. Eine Methode zum Teilen einer Datei in Blöcke einer bestimmten Größe und zum Zählen der Anzahl der Zeilenumbrüche von der Rückseite des nachfolgenden Blocks.
Nicht zu früh.
Als nächstes folgt die Implementierung, dass, wenn Sie aufgefordert werden, Tail zu schreiben, dies in diese Richtung erfolgt.
tail_mmap.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
void tail(char *fname, int n_lines) {
int fd = open(fname, O_RDONLY);
struct stat st;
fstat(fd, &st);
int fsize = st.st_size;
char *map = mmap(0, fsize, PROT_READ, MAP_PRIVATE, fd, 0);
char *cursor = map+fsize;
if (fsize > 0 && cursor[-1] != '\n') n_lines--;
for (int i = 0; i < fsize; i++){
cursor--;
if (*cursor == '\n') n_lines--;
if (n_lines < 0){
cursor++;
break;
}
}
write(1, cursor, fsize-(cursor-map));
munmap(map, fsize);
close(fd);
}
int main(int argc, char *argv[]){
if(argc != 3) exit(EXIT_FAILURE);
tail(argv[1], atoi(argv[2]));
exit(EXIT_SUCCESS);
}
Eine Methode zum Zählen von hinten mit mmap.
Es gibt viele Vorzüge. Es ist sehr schnell. Schneller als der ursprüngliche Schwanz.