优化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, 0this.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 + 1this.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 }