Subject:
The most popular J2SDK version is the 1.3 series. Using this version of the developer requires random access to the file, you have to use the Randomaccessfile class. Its I/O performance is far from the similar performance of other common development languages, which seriously affects the running efficiency of the program.
Developers urgently need to improve efficiency, the following analysis of the source code of Randomaccessfile and other file classes, find out the crux of the problem, and improve the optimization, create a "sex/price ratio" is a good random file access class Bufferedrandomaccessfile.
Do a basic test before improving: byte copy of a 12-megabyte file (this involves reading and writing).
Read |
Write |
Elapsed Time (sec) |
Randomaccessfile |
Randomaccessfile |
95.848 |
Bufferedinputstream + DataInputStream |
Bufferedoutputstream + DataOutputStream |
2.935 |
We can see that the gap is about 32 times times, and the randomaccessfile is too slow. First look at the key parts of the source code, comparative analysis, to find out why.
1. 1. [Randomaccessfile]
public class RandomAccessFile implements DataOutput, DataInput {
public final byte readByte() throws IOException {
int ch = this.read();
if (ch < 0)
throw new EOFException();
return (byte)(ch);
}
public native int read() throws IOException;
public final void writeByte(int v) throws IOException {
write(v);
}
public native void write(int b) throws IOException;
}
As you can see, the randomaccessfile requires an I/O operation on the disk every read/write byte.
1. 2. [Bufferedinputstream]
public class Bufferedinputstream extends FilterInputStream {
private static int defaultbuffersize = 2048; protected byte buf[]; Create a read buffer
Public bufferedinputstream (inputstream in, int size) {
Super (in);
if (size <= 0) {
throw new IllegalArgumentException ("Buffer size <= 0");
BUF = new Byte[size];
}
Public synchronized int read () throws IOException {
Ensureopen ();
if (POS >= count) {
Fill ();
if (POS >= count)
Return-1;
return buf[pos++] & 0xff;//read directly from buf[
}
private void Fill () throws IOException {
if (ma Rkpos < 0)
pos = 0; /* No mark:throw away the buffer */
Else if (pos >= buf.length) * No room left in buffer */
if (Markpo s > 0) {/* can throw away early part of the buffer */
int sz = Pos-markpos;
System.arraycopy (buf, Markpos, buf, 0, SZ);br> pos = sz;
Markpos = 0;
} else if (buf.length >= marklimit) {
Markpos =-1; /* Buffer got too big, invalidate mark */
pos = 0; /* Drop Buffer Contents */
} else {/* Grow buffer */
int NSZ = pos * 2;
if (Nsz > Marklimit)
Nsz = Marklimit;
byte nbuf[] = new Byte[nsz];
System.arraycopy (buf, 0, nbuf, 0, POS);
buf = nbuf;
}
Count = pos;
int n = in.read (buf, POS, buf.length-pos);
if (n > 0)
Count = n + pos;
}
}