回答編集履歴

3

追記

2020/12/20 11:55

投稿

otn
otn

スコア86316

test CHANGED
@@ -101,3 +101,47 @@
101
101
  end
102
102
 
103
103
  ```
104
+
105
+ 3.最終行の末尾に`\n`が無いケースと、大きさゼロのファイルの対応
106
+
107
+ あわせて、少しスッキリさせる。
108
+
109
+ ```Ruby
110
+
111
+ def tail(lines, filename)
112
+
113
+ File.open(filename) do |io|
114
+
115
+ io.seek(-1, IO::SEEK_END) rescue nil
116
+
117
+ chars_array = [io.read(1)]
118
+
119
+ n = 0
120
+
121
+ while io.pos >= 2 # 普通の「EOFでない間」に相当
122
+
123
+ io.seek(-2, IO::SEEK_CUR)
124
+
125
+ c = io.read(1)
126
+
127
+ if c == "\n"
128
+
129
+ n += 1
130
+
131
+ break if n >= lines
132
+
133
+ end
134
+
135
+ chars_array << c
136
+
137
+ end
138
+
139
+
140
+
141
+ p chars_array.reverse.join
142
+
143
+ end
144
+
145
+ end
146
+
147
+ ```

2

追記

2020/12/20 11:55

投稿

otn
otn

スコア86316

test CHANGED
@@ -19,3 +19,85 @@
19
19
  案3:
20
20
 
21
21
  その折衷案
22
+
23
+
24
+
25
+ #追記
26
+
27
+ 質問追記に対しての改善。
28
+
29
+ 1.末尾のバイトが欠ける、および、表示が`\n`から始まる点の対応
30
+
31
+ ```Ruby
32
+
33
+ def tail(lines, filename)
34
+
35
+ File.open(filename) do |io|
36
+
37
+ chars_array = []
38
+
39
+
40
+
41
+ io.seek(-1, IO::SEEK_END)
42
+
43
+ while chars_array.count("\n") < lines+1
44
+
45
+ chars_array << io.read(1)
46
+
47
+ io.seek(-2, IO::SEEK_CUR)
48
+
49
+ end
50
+
51
+ chars_array.pop
52
+
53
+
54
+
55
+ p chars_array.reverse.join
56
+
57
+ end
58
+
59
+ end
60
+
61
+ ```
62
+
63
+ 2.さらに、大きすぎる行数を指定した場合の対応
64
+
65
+ ```Ruby
66
+
67
+ def tail(lines, filename)
68
+
69
+ File.open(filename) do |io|
70
+
71
+ chars_array = []
72
+
73
+
74
+
75
+ io.seek(-1, IO::SEEK_END)
76
+
77
+ while chars_array.count("\n") < lines+1
78
+
79
+ chars_array << io.read(1)
80
+
81
+ if io.pos == 1
82
+
83
+ chars_array << :DUMMY
84
+
85
+ break
86
+
87
+ end
88
+
89
+ io.seek(-2, IO::SEEK_CUR)
90
+
91
+ end
92
+
93
+ chars_array.pop
94
+
95
+
96
+
97
+ p chars_array.reverse.join
98
+
99
+ end
100
+
101
+ end
102
+
103
+ ```

1

追記

2020/12/20 09:06

投稿

otn
otn

スコア86316

test CHANGED
@@ -15,3 +15,7 @@
15
15
  案2:
16
16
 
17
17
  末尾から1バイトずつ遡って読んでいき(毎回`seek`する)、`lines`個目の改行を認識して、読んだ物を表示
18
+
19
+ 案3:
20
+
21
+ その折衷案