1
2
3
4
5
6
7
8
9
10
11 package psiprobe.tools;
12
13 import java.io.BufferedInputStream;
14 import java.io.ByteArrayOutputStream;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.nio.charset.Charset;
18 import java.nio.charset.StandardCharsets;
19
20
21
22
23
24
25
26
27 public class BackwardsLineReader {
28
29
30 private BufferedInputStream bis;
31
32
33 private boolean skipLineFeed = true;
34
35
36 private String encoding;
37
38
39
40
41
42
43 public BackwardsLineReader(InputStream is) {
44 this(is, null);
45 }
46
47
48
49
50
51
52
53 public BackwardsLineReader(InputStream is, String encoding) {
54 this.bis = new BufferedInputStream(is, 8192);
55 this.encoding = encoding;
56 }
57
58
59
60
61
62
63
64
65 public String readLine() throws IOException {
66 ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
67 boolean empty = false;
68 while (true) {
69 byte chr = (byte) bis.read();
70 if (chr == -1) {
71
72
73 if (baos.toByteArray().length == 0) {
74 empty = true;
75 }
76 break;
77 }
78 if (chr == '\n') {
79 skipLineFeed = false;
80
81 break;
82 }
83 if (chr == '\r') {
84 if (skipLineFeed) {
85
86 break;
87 }
88
89
90 continue;
91 }
92 baos.write(chr);
93 }
94 if (!empty) {
95 byte[] byteArray = baos.toByteArray();
96 reverse(byteArray);
97 return encoding == null ? new String(byteArray, StandardCharsets.UTF_8)
98 : new String(byteArray, Charset.forName(encoding));
99 }
100
101 return null;
102 }
103
104
105
106
107
108
109 public void close() throws IOException {
110 if (bis != null) {
111 bis.close();
112 }
113 }
114
115
116
117
118
119
120 private void reverse(byte[] byteArray) {
121 for (int i = 0; i < byteArray.length / 2; i++) {
122 byte temp = byteArray[i];
123 byteArray[i] = byteArray[byteArray.length - i - 1];
124 byteArray[byteArray.length - i - 1] = temp;
125 }
126 }
127
128 }