优化RandomAccessFile类后完整版代码
1.BufferedRandomAccessFile.java类
1 package kbps.io;
2
3 import java.io.RandomAccessFile;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.FileNotFoundException;
7 import java.util.ResourceBundle;
8
9 /**
10 * <p>Title: BufferedRandomAccessFile</p>
11 * <p>Description: this class provide Buffered Read & Write by extend RandomAccessFile</p>
12 * <p>Copyright: Copyright (c) 2002 Cui Zhixiang </p>
13 * <p>Company: soho </p>
14 * @author Cui Zhixiang
15 * @version 1.0, 2002/10/12
16 */
17
18 public class BufferedRandomAccessFile extends RandomAccessFile {
19
20 static ResourceBundle res = ResourceBundle.getBundle("kbps.io.Res");
21 private static final int DEFAULT_BUFFER_BIT_LEN = 10;
22 private static final int DEFAULT_BUFFER_SIZE = 1 << DEFAULT_BUFFER_BIT_LEN;
23
24 protected byte buf[];
25 protected int bufbitlen;
26 protected int bufsize;
27 protected long bufmask;
28 protected boolean bufdirty;
29 protected int bufusedsize;
30 protected long curpos;
31
32 protected long bufstartpos;
33 protected long bufendpos;
34 protected long fileendpos;
35
36 protected boolean append;
37 protected String filename;
38 protected long initfilelen;
39
40 public BufferedRandomAccessFile(String name) throws IOException {
41 this(name, res.getString("r"), DEFAULT_BUFFER_BIT_LEN);
42 }
43
44 public BufferedRandomAccessFile(File file) throws IOException, FileNotFoundException {
45 this(file.getPath(), res.getString("r"), DEFAULT_BUFFER_BIT_LEN);
46 }
47
48 public BufferedRandomAccessFile(String name, int bufbitlen) throws IOException {
49 this(name, res.getString("r"), bufbitlen);
50 }
51
52 public BufferedRandomAccessFile(File file, int bufbitlen) throws IOException, FileNotFoundException {
53 this(file.getPath(), res.getString("r"), bufbitlen);
54 }
55
56 public BufferedRandomAccessFile(String name, String mode) throws IOException {
57 this(name, mode, DEFAULT_BUFFER_BIT_LEN);
58 }
59
60 public BufferedRandomAccessFile(File file, String mode) throws IOException, FileNotFoundException {
61 this(file.getPath(), mode, DEFAULT_BUFFER_BIT_LEN);
62 }
63
64 public BufferedRandomAccessFile(String name, String mode, int bufbitlen) throws IOException {
65 super(name, mode);
66 this.init(name, mode, bufbitlen);
67 }
68
69 public BufferedRandomAccessFile(File file, String mode, int bufbitlen) throws IOException, FileNotFoundException {
70 this(file.getPath(), mode, bufbitlen);
71 }
72
73 private void init(String name, String mode, int bufbitlen) throws IOException {
74 if (mode.equals(res.getString("r")) == true) {
75 this.append = false;
76 } else {
77 this.append = true;
78 }
79
80 this.filename = name;
81 this.initfilelen = super.length();
82 this.fileendpos = this.initfilelen - 1;
83 this.curpos = super.getFilePointer();
84
85 if (bufbitlen < 0) {
86 throw new IllegalArgumentException(res.getString("bufbitlen_size_must_0"));
87 }
88
89 this.bufbitlen = bufbitlen;
90 this.bufsize = 1 << bufbitlen;
91 this.buf = new byte[this.bufsize];
92 this.bufmask = ~((long)this.bufsize - 1L);
93 this.bufdirty = false;
94 this.bufusedsize = 0;
95 this.bufstartpos = -1;
96 this.bufendpos = -1;
97 }
98
99 private void flushbuf() throws IOException {
100 if (this.bufdirty == true) {
101 if (super.getFilePointer() != this.bufstartpos) {
102 super.seek(this.bufstartpos);
103 }
104 super.write(this.buf, 0, this.bufusedsize);
105 this.bufdirty = false;
106 }
107 }
108
109 private int fillbuf() throws IOException {
110 super.seek(this.bufstartpos);
111 this.bufdirty = false;
112 return super.read(this.buf);
113 }
114
115 public byte read(long pos) throws IOException {
116 if (pos < this.bufstartpos || pos > this.bufendpos) {
117 this.flushbuf();
118 this.seek(pos);
119
120 if ((pos < this.bufstartpos) || (pos > this.bufendpos)) {
121 throw new IOException();
122 }
123 }
124 this.curpos = pos;
125 return this.buf[(int)(pos - this.bufstartpos)];
126 }
127
128 public boolean write(byte bw) throws IOException {
129 return this.write(bw, this.curpos);
130 }
131
132 public boolean append(byte bw) throws IOException {
133 return this.write(bw, this.fileendpos + 1);
134 }
135
136 public boolean write(byte bw, long pos) throws IOException {
137
138 if ((pos >= this.bufstartpos) && (pos <= this.bufendpos)) { // write pos in buf
139 this.buf[(int)(pos - this.bufstartpos)] = bw;
140 this.bufdirty = true;
141
142 if (pos == this.fileendpos + 1) { // write pos is append pos
143 this.fileendpos++;
144 this.bufusedsize++;
145 }
146 } else { // write pos not in buf
147 this.seek(pos);
148
149 if ((pos >= 0) && (pos <= this.fileendpos) && (this.fileendpos != 0)) { // write pos is modify file
150 this.buf[(int)(pos - this.bufstartpos)] = bw;
151
152 } else if (((pos == 0) && (this.fileendpos == 0)) || (pos == this.fileendpos + 1)) { // write pos is append pos
153 this.buf[0] = bw;
154 this.fileendpos++;
155 this.bufusedsize = 1;
156 } else {
157 throw new IndexOutOfBoundsException();
158 }
159 this.bufdirty = true;
160 }
161 this.curpos = pos;
162 return true;
163 }
164
165 public void write(byte b[], int off, int len) throws IOException {
166
167 long writeendpos = this.curpos + len - 1;
168
169 if (writeendpos <= this.bufendpos) { // b[] in cur buf
170 System.arraycopy(b, off, this.buf, (int)(this.curpos - this.bufstartpos), len);
171 this.bufdirty = true;
172 this.bufusedsize = (int)(writeendpos - this.bufstartpos + 1);//(int)(this.curpos - this.bufstartpos + len - 1);
173
174 } else { // b[] not in cur buf
175 super.seek(this.curpos);
176 super.write(b, off, len);
177 }
178
179 if (writeendpos > this.fileendpos)
180 this.fileendpos = writeendpos;
181
182 this.seek(writeendpos+1);
183 }
184
185 public int read(byte b[], int off, int len) throws IOException {
186
187 long readendpos = this.curpos + len - 1;
188
189 if (readendpos <= this.bufendpos && readendpos <= this.fileendpos ) { // read in buf
190 System.arraycopy(this.buf, (int)(this.curpos - this.bufstartpos), b, off, len);
191 } else { // read b[] size > buf[]
192
193 if (readendpos > this.fileendpos) { // read b[] part in file
194 len = (int)(this.length() - this.curpos + 1);
195 }
196
197 super.seek(this.curpos);
198 len = super.read(b, off, len);
199 readendpos = this.curpos + len - 1;
200 }
201 this.seek(readendpos + 1);
202 return len;
203 }
204
205 public void write(byte b[]) throws IOException {
206 this.write(b, 0, b.length);
207 }
208
209 public int read(byte b[]) throws IOException {
210 return this.read(b, 0, b.length);
211 }
212
213 public void seek(long pos) throws IOException {
214
215 if ((pos < this.bufstartpos) || (pos > this.bufendpos)) { // seek pos not in buf
216 this.flushbuf();
217
218 if ((pos >= 0) && (pos <= this.fileendpos) && (this.fileendpos != 0)) { // seek pos in file (file length > 0)
219 this.bufstartpos = pos & this.bufmask;
220 this.bufusedsize = this.fillbuf();
221
222 } else if (((pos == 0) && (this.fileendpos == 0)) || (pos == this.fileendpos + 1)) { // seek pos is append pos
223
224 this.bufstartpos = pos;
225 this.bufusedsize = 0;
226 }
227 this.bufendpos = this.bufstartpos + this.bufsize - 1;
228 }
229 this.curpos = pos;
230 }
231
232 public long length() throws IOException {
233 return this.max(this.fileendpos + 1, this.initfilelen);
234 }
235
236 public void setLength(long newLength) throws IOException {
237 if (newLength > 0) {
238 this.fileendpos = newLength - 1;
239 } else {
240 this.fileendpos = 0;
241 }
242 super.setLength(newLength);
243 }
244 public long getFilePointer() throws IOException {
245 return this.curpos;
246 }
247
248 private long max(long a, long b) {
249 if (a > b) return a;
250 return b;
251 }
252
253 public void close() throws IOException {
254 this.flushbuf();
255 super.close();
256 }
257
258 public static void main(String[] args) throws IOException {
259 long readfilelen = 0;
260 BufferedRandomAccessFile brafReadFile, brafWriteFile;
261
262 brafReadFile = new BufferedRandomAccessFile("C:\\WINNT\\Fonts\\STKAITI.TTF");
263 readfilelen = brafReadFile.initfilelen;
264 brafWriteFile = new BufferedRandomAccessFile(".\\STKAITI.001", "rw", 10);
265
266 byte buf[] = new byte[1024];
267 int readcount;
268
269 long start = System.currentTimeMillis();
270
271 while((readcount = brafReadFile.read(buf)) != -1) {
272 brafWriteFile.write(buf, 0, readcount);
273 }
274
275 brafWriteFile.close();
276 brafReadFile.close();
277
278 System.out.println("BufferedRandomAccessFile Copy & Write File: "
279 + brafReadFile.filename
280 + " FileSize: "
281 + java.lang.Integer.toString((int)readfilelen >> 1024)
282 + " (KB) "
283 + "Spend: "
284 +(double)(System.currentTimeMillis()-start) / 1000
285 + "(s)");
286
287 java.io.FileInputStream fdin = new java.io.FileInputStream("C:\\WINNT\\Fonts\\STKAITI.TTF");
288 java.io.BufferedInputStream bis = new java.io.BufferedInputStream(fdin, 1024);
289 java.io.DataInputStream dis = new java.io.DataInputStream(bis);
290
291 java.io.FileOutputStream fdout = new java.io.FileOutputStream(".\\STKAITI.002");
292 java.io.BufferedOutputStream bos = new java.io.BufferedOutputStream(fdout, 1024);
293 java.io.DataOutputStream dos = new java.io.DataOutputStream(bos);
294
295 start = System.currentTimeMillis();
296
297 for (int i = 0; i < readfilelen; i++) {
298 dos.write(dis.readByte());
299 }
300
301 dos.close();
302 dis.close();
303
304 System.out.println("DataBufferedios Copy & Write File: "
305 + brafReadFile.filename
306 + " FileSize: "
307 + java.lang.Integer.toString((int)readfilelen >> 1024)
308 + " (KB) "
309 + "Spend: "
310 + (double)(System.currentTimeMillis()-start) / 1000
311 + "(s)");
312 }
313 }
314
2.Res.java类
1 package kbps.io;
2
3 import java.util.*;
4
5 public class Res extends java.util.ListResourceBundle {
6 static final Object[][] contents = new String[][]{
7 { "r", "r" },
8 { "bufbitlen_size_must_0", "bufbitlen size must >= 0" },
9 { "rw", "rw" },
10 { "BufferedRandomAccess", "BufferedRandomAccessFile Copy & Write File: " },
11 { "FileSize_", " FileSize: " },
12 { "_KB_", " (KB) " },
13 { "Spend_", "Spend: " },
14 { "_s_", "(s)" },
15 { "DataBufferedios_Copy", "DataBufferedios Copy & Write File: " }};
16 public Object[][] getContents() {
17 return contents;
18 }
19 }