优化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  }