1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.nuiton.util;
24
25 import java.io.Closeable;
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.RandomAccessFile;
29
30
31
32
33
34
35
36
37 public class ReverseFileReader implements Closeable {
38 protected String filename;
39
40 protected RandomAccessFile randomfile;
41
42 protected long position;
43
44 public ReverseFileReader(File file) throws IOException {
45
46 randomfile = new RandomAccessFile(file, "r");
47
48 position = randomfile.length();
49
50
51 randomfile.seek(position);
52
53 String thisLine = randomfile.readLine();
54 while (thisLine == null) {
55 position--;
56 randomfile.seek(position);
57 thisLine = randomfile.readLine();
58 randomfile.seek(position);
59 }
60 }
61
62 public ReverseFileReader(String filename) throws IOException {
63 this(filename != null ? new File(filename) : null);
64 }
65
66
67
68
69
70
71
72
73 public String readLine() throws IOException {
74 int thisCode;
75 char thisChar;
76 String finalLine = "";
77
78
79
80 if (position < 0) {
81 return null;
82 }
83
84 for (; ; ) {
85
86 if (position < 0) {
87 break;
88 }
89
90 randomfile.seek(position);
91
92
93 thisCode = randomfile.readByte();
94 thisChar = (char) thisCode;
95
96
97 if (thisCode == 13 || thisCode == 10) {
98
99
100 randomfile.seek(position - 1);
101 int nextCode = randomfile.readByte();
102 if (thisCode == 10 && nextCode == 13
103 || thisCode == 13 && nextCode == 10) {
104
105 position = position - 1;
106 }
107
108 position--;
109 break;
110 } else {
111
112 finalLine = thisChar + finalLine;
113 }
114
115 position--;
116 }
117
118 return finalLine;
119 }
120
121 @Override
122 public void close() throws IOException {
123 if (randomfile != null) {
124 randomfile.close();
125 }
126 }
127
128 @Override
129 protected void finalize() throws Throwable {
130 close();
131 super.finalize();
132 }
133 }