-
-
Save zhu2688/d331fea5886d9e19dc9f32d947f5552c to your computer and use it in GitHub Desktop.
tail in ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Tail | |
| class << self | |
| def tail(path, n) | |
| file = File.open(path, "r") | |
| buffer_s = 512 | |
| line_count = 0 | |
| file.seek(0, IO::SEEK_END) | |
| offset = file.pos # we start at the end | |
| while line_count <= n && offset > 0 | |
| to_read = if (offset - buffer_s) < 0 | |
| offset | |
| else | |
| buffer_s | |
| end | |
| file.seek(offset-to_read) | |
| data = file.read(to_read) | |
| data.reverse.each_char do |c| | |
| if line_count > n | |
| offset += 1 | |
| break | |
| end | |
| offset -= 1 | |
| if c == "\n" | |
| line_count += 1 | |
| end | |
| end | |
| end | |
| file.seek(offset) | |
| data = file.read | |
| end | |
| end | |
| end | |
| require "minitest/autorun" | |
| class TestTail < Minitest::Test | |
| TEST_PATH = "/tmp/test-tail" | |
| def setup | |
| @file = File.open(TEST_PATH, "w") | |
| end | |
| def text_from(i,j) | |
| out = "" | |
| i.upto(j) do |x| | |
| out << "line #{x}\n" | |
| end | |
| out | |
| end | |
| def test_empty_file | |
| @file.write("") && @file.close | |
| assert_equal "", Tail.tail(TEST_PATH, 10) | |
| end | |
| def test_smaller_line_count | |
| @file.write(text_from(0,3)) && @file.close | |
| assert_equal text_from(0,3), Tail.tail(TEST_PATH, 10) | |
| end | |
| def test_same_line_count | |
| @file.write(text_from(0,9)) && @file.close | |
| assert_equal text_from(0,9), Tail.tail(TEST_PATH, 10) | |
| end | |
| def test_larger_line_count | |
| @file.write(text_from(0,12)) && @file.close | |
| assert_equal text_from(3,12), Tail.tail(TEST_PATH, 10) | |
| end | |
| def test_very_long_lines | |
| long_line = ("apples and oranges" * 1000) + "\n" | |
| bunch_of_long_lines = long_line * 12 | |
| @file.write(bunch_of_long_lines) && @file.close | |
| assert_equal (long_line * 10), Tail.tail(TEST_PATH, 10) | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment