Java でストリームの末尾数行を捨てる
末尾の行を捨てるためには一旦ファイルを全部読まなきゃいけないかと思ったけど、捨てたい行数を先読みしておけば良いという感じでした。
import java.io.*; import java.util.LinkedList; import java.util.Queue; // ファイルの末尾数行捨てる BufferedReader class TailIgnoringBufferedReader extends Reader { private final BufferedReader _reader; private final int num; Queue<String> queue = new LinkedList<>(); TailIgnoringBufferedReader(Reader in, int num) { this._reader = new BufferedReader(in); this.num = num; } public String readLine() throws IOException { while (this.queue.size() <= this.num) { String line = this._reader.readLine(); if (line == null) return null; this.queue.add(line); } return this.queue.poll(); } @Override public int read(char[] cbuf, int off, int len) throws IOException { return this._reader.read(); } @Override public void close() throws IOException { this._reader.close(); } }
( lines
とかは未実装。BufferedReader と名付けていいかは微妙なところかも。)
こんな感じで使えます
InputStream data = new ByteArrayInputStream("1\n2\n3\n4\n5\n6\n7\n8\n9".getBytes()); try (TailIgnoringBufferedReader reader = new TailIgnoringBufferedReader(new InputStreamReader(data), 5)) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); }
先頭も捨てられるようにすれば任意の切り出し方ができるようになる
感想
InputStream 系のコードは書いていて楽しい
read
とかでも対応するにはどうするべきなんだろうか?(先読みは同じで、 currentLine
みたいなインスタンス変数持ってそこから返していく、空になったら Queue からロードする感じかな)