这些天一直在对文件进行读写操作,为了性能,换了好几种方式,我下面贴出来:
/** * 随机读取文件内容 * * @param fileName */ public static String readFileByRandomAccess(String path) { StringBuffer sb = new StringBuffer(); RandomAccessFile randomFile = null; try { // 打开一个随机访问文件流,按只读方式 randomFile = new RandomAccessFile(path, "rw"); byte[] bytes = new byte[1024]; int byteread = 0; while ((byteread = randomFile.read(bytes)) != -1) { // System.out.write(bytes, 0, byteread); sb.append(new String(bytes, 0, byteread)); } } catch (IOException e) { e.printStackTrace(); } finally { if (randomFile != null) { try { randomFile.close(); } catch (IOException e1) { } } } return sb.toString(); }
/** * 以行为单位读取文件,常用于读面向行的格式化文件 * * @param fileName */ public static String readFileByLines(String path) { StringBuffer sb = new StringBuffer(); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(path)); String tempString = null; while ((tempString = reader.readLine()) != null) { sb.append(tempString).append(System.getProperty("line.separator"));// 显示行号 } } catch (IOException e) { e.printStackTrace(); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { System.err.println("流关闭失败"); } } return sb.toString(); }
/** * 使用Java.nio ByteBuffer字节将一个文件输出 * * @param filePath */ public static String readFileByBybeBuffer(String path) { StringBuffer sb = new StringBuffer(); FileInputStream in = null; FileOutputStream out = null; try { // 获取源文件和目标文件的输入输出流 in = new FileInputStream(path); // 获取输入输出通道 FileChannel fcIn = in.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); CharBuffer charBuffer = null; Charset charset = Charset.forName("UTF-8"); CharsetDecoder decoder = charset.newDecoder(); while (true) { // clear方法重设缓冲区,使它可以接受读入的数据 buffer.clear(); // 从输入通道中将数据读到缓冲区 int r = fcIn.read(buffer); if (r == -1) { break; } charBuffer = decoder.decode(buffer); // flip方法让缓冲区可以将新读入的数据写入另一个通道 buffer.flip(); sb.append(charBuffer.toString()); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (in != null && out != null) { in.close(); out.close(); } } catch (IOException e) { e.printStackTrace(); } } //System.out.println(sb.toString()); return sb.toString(); }
/** * 通过scanner的方式读取文件 * * @param fileName * @return */ public static String readByScanner(String path) { StringBuffer sb = new StringBuffer(); Scanner s = null; try { File f = new File(path); s = new Scanner(f); while (s.hasNext()) { sb.append(s.next()); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if(s!=null)s.close(); } return sb.toString(); }
我们来测试下:
String fileName="Z:\\flume\\flume\\conf\\ErrLog"; long t1=OperateUtil.getTime(); OperateUtil.readByScanner(fileName); long t2=OperateUtil.getTime(); OperateUtil.readFileByBybeBuffer(fileName); long t3=OperateUtil.getTime(); OperateUtil.readFileByLines(fileName); long t4=OperateUtil.getTime(); OperateUtil.readFileByRandomAccess(fileName); long t5=OperateUtil.getTime(); System.out.println("readByScanner:"+(t2-t1)); System.out.println("readFileByBybeBuffer:"+(t3-t2)); System.out.println("readFileByLines:"+(t4-t3)); System.out.println("readFileByRandomAccess:"+(t5-t4)); ErrLog的文件大小是65M。
下面看下测试结果:
readByScanner:6180 readFileByBybeBuffer:171 readFileByLines:468 readFileByRandomAccess:531
经过多次测试,依旧发现readFileByBybeBuffer这个方式的效率更好,使用的是NIO