我们知道Java中一般的输入输出流类都是用单字节的读取方法来进行I/O操作的,也就是说每次只读写一个字节的数据,这种方法显然繁琐低效。如果从设备读取10M的文件,每次读取一个字节,完成操作将需要做10M/次I/O操作,I/O操作又是一件相当耗时的事情,无疑在很大程度上降低了系统的性能。
Java中专门提供提高I/O效率的缓冲类,这好比在数据读写时提供一个临时缓冲区,每次读取一个缓冲区大小的数据,将这数据库一次性写入目标设备。下图中分别为两种读取方式。
举个简单例子,在A地有10000本书需要搬到B地,如果一次搬1本,需要10000次。如果每次取1000本放到一个货车上,运到B地,需要10次完成。货车相当于是缓存区。同样道理,开设一个数据缓存区每次读取一数据块对于提高读取效率有显著提升。下面用一个具体代码示例来表示二者的性能差别。
Java代码
import java.io.*; /******************************************************************************* * * @author pengcqu * */ public class TestBuffer { public static void main(String args[]) throws IOException { TestBuffer br = new TestBuffer(); String from = "d:/a/1.MP3"; long startTime = System.currentTimeMillis(); br.readWrite(from,"d:/b/2.MP3"); long endTime = System.currentTimeMillis(); System.out.println("直接读取耗时:" + (endTime - startTime) +"ms"); long startTime1 = System.currentTimeMillis(); br.readWriteWithBuffer(from, "d:/b/3.MP3"); long endTime1 = System.currentTimeMillis(); System.out.println("使用缓冲区读取耗时:" + (endTime1 - startTime1) +"ms"); } /*************************************************************************** * 直接读取文件 * * @param from * @param to * @throws IOException */ public static void readWrite(String from, String to) throws IOException { InputStream in = null; OutputStream out = null; try { in = new FileInputStream(from); out = new FileOutputStream(to); while (true) { int data = in.read(); if (data == -1) { break; } out.write(data); } } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } } /*************************************************************************** * 使用缓存区读写文件 * @param from * @param to * @throws IOException */ public static void readWriteWithBuffer(String from, String to) throws IOException { InputStream inBuffer = null; OutputStream outBuffer = null; try { inBuffer = new BufferedInputStream(new FileInputStream(from)); outBuffer = new BufferedOutputStream(new FileOutputStream(to)); while (true) { int data = inBuffer.read(); if (data == -1) { break; } outBuffer.write(data); } } finally { if (inBuffer != null) { inBuffer.close(); } if (outBuffer != null) { outBuffer.close(); } } } }
结果:对于5.8M大小的文件,直接读写耗时:39266ms;使用缓冲区读写耗时:719ms。可见通过Buffer读写文件性能的明显优于直接读写。
如有理解不妥之处,请各位高手补充意见。