Java 之 文件读写及性能比较总结

来源:互联网 发布:js时间格式化为时间戳 编辑:程序博客网 时间:2024/06/08 00:04

干Java这么久,一直在做WEB相关的项目,一些基础类差不多都已经忘记。经常想得捡起,但总是因为一些原因,不能如愿。

其实不是没有时间,只是有些时候疲于总结,今得空,下定决心将丢掉的都给捡起来。

文件读写是一个在项目中经常遇到的工作,有些时候是因为维护,有些时候是新功能开发。我们的任务总是很重,工作节奏很快,快到我们不能停下脚步去总结。

文件读写有以下几种常用的方法

1、字节读写(InputStream/OutputStream)

2、字符读取(FileReader/FileWriter)

3、行读取(BufferedReader/BufferedWriter)

代码(以读取为例):

[java] view plain copy
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
/**
* 文件读取类

* 1、按字节读取文件内容

* 2、按字符读取文件内容

* 3、按行读取文件内容

* @author qin_xijuan
*
*/
public class FileOperate {

private static final String FILE_PATH = “d:/work/the List of Beautiful Music.txt”;  /**  * 以字节为单位读取文件内容  * @param filePath:需要读取的文件路径  */  public static void readFileByByte(String filePath) {      File file = new File(filePath);      // InputStream:此抽象类是表示字节输入流的所有类的超类。      InputStream ins = null ;      try{          // FileInputStream:从文件系统中的某个文件中获得输入字节。          ins = new FileInputStream(file);          int temp ;          // read():从输入流中读取数据的下一个字节。          while((temp = ins.read())!=-1){              System.out.write(temp);          }      }catch(Exception e){          e.getStackTrace();      }finally{          if (ins != null){              try{                  ins.close();              }catch(IOException e){                  e.getStackTrace();              }          }      }  }  /**  * 以字符为单位读取文件内容  * @param filePath  */  public static void readFileByCharacter(String filePath){      File file = new File(filePath);      // FileReader:用来读取字符文件的便捷类。      FileReader reader = null;      try{          reader = new FileReader(file);          int temp ;          while((temp = reader.read()) != -1){              if (((char) temp) != ‘\r’) {                  System.out.print((char) temp);              }          }      }catch(IOException e){          e.getStackTrace();      }finally{          if (reader != null){              try {                  reader.close();              } catch (IOException e) {                  e.printStackTrace();              }          }      }  }  /**  * 以行为单位读取文件内容  * @param filePath  */  public static void readFileByLine(String filePath){      File file = new File(filePath);      // BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。      BufferedReader buf = null;      try{          // FileReader:用来读取字符文件的便捷类。          buf = new BufferedReader(new FileReader(file));          // buf = new BufferedReader(new InputStreamReader(new FileInputStream(file)));          String temp = null ;          while ((temp = buf.readLine()) != null ){              System.out.println(temp);          }      }catch(Exception e){          e.getStackTrace();      }finally{          if(buf != null){              try{                  buf.close();              } catch (IOException e) {                  e.getStackTrace();              }          }      }  }  public static void main(String args[]) {      readFileByByte(FILE_PATH);      readFileByCharacter(FILE_PATH);      readFileByLine(FILE_PATH);  }  

}
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; /* 文件读取类
* 1、按字节读取文件内容
* 2、按字符读取文件内容
* 3、按行读取文件内容
* @author qin_xijuan * / public class FileOperate { private static final String FILE_PATH = “d:/work/the List of Beautiful Music.txt”; /* * 以字节为单位读取文件内容 * @param filePath:需要读取的文件路径 / public static void readFileByByte(String filePath) { File file = new File(filePath); // InputStream:此抽象类是表示字节输入流的所有类的超类。 InputStream ins = null ; try{ // FileInputStream:从文件系统中的某个文件中获得输入字节。 ins = new FileInputStream(file); int temp ; // read():从输入流中读取数据的下一个字节。 while((temp = ins.read())!=-1){ System.out.write(temp); } }catch(Exception e){ e.getStackTrace(); }finally{ if (ins != null){ try{ ins.close(); }catch(IOException e){ e.getStackTrace(); } } } } /* * 以字符为单位读取文件内容 * @param filePath / public static void readFileByCharacter(String filePath){ File file = new File(filePath); // FileReader:用来读取字符文件的便捷类。 FileReader reader = null; try{ reader = new FileReader(file); int temp ; while((temp = reader.read()) != -1){ if (((char) temp) != ‘\r’) { System.out.print((char) temp); } } }catch(IOException e){ e.getStackTrace(); }finally{ if (reader != null){ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* * 以行为单位读取文件内容 * @param filePath */ public static void readFileByLine(String filePath){ File file = new File(filePath); // BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 BufferedReader buf = null; try{ // FileReader:用来读取字符文件的便捷类。 buf = new BufferedReader(new FileReader(file)); // buf = new BufferedReader(new InputStreamReader(new FileInputStream(file))); String temp = null ; while ((temp = buf.readLine()) != null ){ System.out.println(temp); } }catch(Exception e){ e.getStackTrace(); }finally{ if(buf != null){ try{ buf.close(); } catch (IOException e) { e.getStackTrace(); } } } } public static void main(String args[]) { readFileByByte(FILE_PATH); readFileByCharacter(FILE_PATH); readFileByLine(FILE_PATH); } }
// —————————————————————– 分割线 —————————————————————————–
再经过两位同行的提点下,我对之前写的文件做了点修改,并通过读写一个1.2M的文本文件来测试各方法的性能。从多次测试结果来看,行读写却是是Java.nio更有效率。

经过修改之后的代码如下:

[java] view plain copy
package com.waddell.basic;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
* 文件读取类

* 1、按字节读取文件内容

* 2、按字符读取文件内容

* 3、按行读取文件内容

*
* @author qin_xijuan
*
*/
public class FileOperate {

private static final String FILE_PATH = “d:/work/jipinwodi.txt”;  /**  * 以字节为单位读写文件内容  *   * @param filePath  *            :需要读取的文件路径  */  public static void readFileByByte(String filePath) {      File file = new File(filePath);      // InputStream:此抽象类是表示字节输入流的所有类的超类。      InputStream ins = null;      OutputStream outs = null;      try {          // FileInputStream:从文件系统中的某个文件中获得输入字节。          ins = new FileInputStream(file);          outs = new FileOutputStream(“d:/work/readFileByByte.txt”);          int temp;          // read():从输入流中读取数据的下一个字节。          while ((temp = ins.read()) != -1) {              outs.write(temp);          }      } catch (Exception e) {          e.getStackTrace();      } finally {          if (ins != null && outs != null) {              try {                  outs.close();                  ins.close();              } catch (IOException e) {                  e.getStackTrace();              }          }      }  }  /**  * 以字符为单位读写文件内容  *   * @param filePath  */  public static void readFileByCharacter(String filePath) {      File file = new File(filePath);      // FileReader:用来读取字符文件的便捷类。      FileReader reader = null;      FileWriter writer = null;      try {          reader = new FileReader(file);          writer = new FileWriter(“d:/work/readFileByCharacter.txt”);          int temp;          while ((temp = reader.read()) != -1) {              writer.write((char)temp);          }      } catch (IOException e) {          e.getStackTrace();      } finally {          if (reader != null && writer != null) {              try {                  reader.close();                  writer.close();              } catch (IOException e) {                  e.printStackTrace();              }          }      }  }  /**  * 以行为单位读写文件内容  *   * @param filePath  */  public static void readFileByLine(String filePath) {      File file = new File(filePath);      // BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。      BufferedReader bufReader = null;      BufferedWriter bufWriter = null;      try {          // FileReader:用来读取字符文件的便捷类。          bufReader = new BufferedReader(new FileReader(file));          bufWriter = new BufferedWriter(new FileWriter(“d:/work/readFileByLine.txt”));          // buf = new BufferedReader(new InputStreamReader(new          // FileInputStream(file)));          String temp = null;          while ((temp = bufReader.readLine()) != null) {              bufWriter.write(temp+”\n”);          }      } catch (Exception e) {          e.getStackTrace();      } finally {          if (bufReader != null && bufWriter != null) {              try {                  bufReader.close();                  bufWriter.close();              } catch (IOException e) {                  e.getStackTrace();              }          }      }  }  /**  * 使用Java.nio ByteBuffer字节将一个文件输出至另一文件  *   * @param filePath  */  public static void readFileByBybeBuffer(String filePath) {      FileInputStream in = null;      FileOutputStream out = null;      try {          // 获取源文件和目标文件的输入输出流            in = new FileInputStream(filePath);          out = new FileOutputStream(“d:/work/readFileByBybeBuffer.txt”);          // 获取输入输出通道          FileChannel fcIn = in.getChannel();          FileChannel fcOut = out.getChannel();          ByteBuffer buffer = ByteBuffer.allocate(1024);          while (true) {              // clear方法重设缓冲区,使它可以接受读入的数据              buffer.clear();              // 从输入通道中将数据读到缓冲区              int r = fcIn.read(buffer);              if (r == -1) {                  break;              }              // flip方法让缓冲区可以将新读入的数据写入另一个通道                buffer.flip();              fcOut.write(buffer);          }      } catch (Exception e) {          e.printStackTrace();      } finally {          if (in != null && out != null) {              try {                  in.close();                  out.close();              } catch (IOException e) {                  e.printStackTrace();              }          }      }  }  public static long getTime(){      return System.currentTimeMillis();  }  public static void main(String args[]) {      long time1 = getTime() ;      // readFileByByte(FILE_PATH);// 8734,8281,8000,7781,8047      // readFileByCharacter(FILE_PATH);// 734, 437, 437, 438, 422      // readFileByLine(FILE_PATH);// 110, 94,  94,  110, 93      readFileByBybeBuffer(FILE_PATH);// 125, 78,  62,  78, 62      long time2 = getTime() ;      System.out.println(time2-time1);  }  

}
package com.waddell.basic; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /* 文件读取类
* 1、按字节读取文件内容
* 2、按字符读取文件内容
* 3、按行读取文件内容
* * @author qin_xijuan * / public class FileOperate { private static final String FILE_PATH = “d:/work/jipinwodi.txt”; /* * 以字节为单位读写文件内容 * * @param filePath * :需要读取的文件路径 / public static void readFileByByte(String filePath) { File file = new File(filePath); // InputStream:此抽象类是表示字节输入流的所有类的超类。 InputStream ins = null; OutputStream outs = null; try { // FileInputStream:从文件系统中的某个文件中获得输入字节。 ins = new FileInputStream(file); outs = new FileOutputStream(“d:/work/readFileByByte.txt”); int temp; // read():从输入流中读取数据的下一个字节。 while ((temp = ins.read()) != -1) { outs.write(temp); } } catch (Exception e) { e.getStackTrace(); } finally { if (ins != null && outs != null) { try { outs.close(); ins.close(); } catch (IOException e) { e.getStackTrace(); } } } } /* * 以字符为单位读写文件内容 * * @param filePath / public static void readFileByCharacter(String filePath) { File file = new File(filePath); // FileReader:用来读取字符文件的便捷类。 FileReader reader = null; FileWriter writer = null; try { reader = new FileReader(file); writer = new FileWriter(“d:/work/readFileByCharacter.txt”); int temp; while ((temp = reader.read()) != -1) { writer.write((char)temp); } } catch (IOException e) { e.getStackTrace(); } finally { if (reader != null && writer != null) { try { reader.close(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* * 以行为单位读写文件内容 * * @param filePath / public static void readFileByLine(String filePath) { File file = new File(filePath); // BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 BufferedReader bufReader = null; BufferedWriter bufWriter = null; try { // FileReader:用来读取字符文件的便捷类。 bufReader = new BufferedReader(new FileReader(file)); bufWriter = new BufferedWriter(new FileWriter(“d:/work/readFileByLine.txt”)); // buf = new BufferedReader(new InputStreamReader(new // FileInputStream(file))); String temp = null; while ((temp = bufReader.readLine()) != null) { bufWriter.write(temp+”\n”); } } catch (Exception e) { e.getStackTrace(); } finally { if (bufReader != null && bufWriter != null) { try { bufReader.close(); bufWriter.close(); } catch (IOException e) { e.getStackTrace(); } } } } /* * 使用Java.nio ByteBuffer字节将一个文件输出至另一文件 * * @param filePath */ public static void readFileByBybeBuffer(String filePath) { FileInputStream in = null; FileOutputStream out = null; try { // 获取源文件和目标文件的输入输出流 in = new FileInputStream(filePath); out = new FileOutputStream(“d:/work/readFileByBybeBuffer.txt”); // 获取输入输出通道 FileChannel fcIn = in.getChannel(); FileChannel fcOut = out.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); while (true) { // clear方法重设缓冲区,使它可以接受读入的数据 buffer.clear(); // 从输入通道中将数据读到缓冲区 int r = fcIn.read(buffer); if (r == -1) { break; } // flip方法让缓冲区可以将新读入的数据写入另一个通道 buffer.flip(); fcOut.write(buffer); } } catch (Exception e) { e.printStackTrace(); } finally { if (in != null && out != null) { try { in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static long getTime(){ return System.currentTimeMillis(); } public static void main(String args[]) { long time1 = getTime() ; // readFileByByte(FILE_PATH);// 8734,8281,8000,7781,8047 // readFileByCharacter(FILE_PATH);// 734, 437, 437, 438, 422 // readFileByLine(FILE_PATH);// 110, 94, 94, 110, 93 readFileByBybeBuffer(FILE_PATH);// 125, 78, 62, 78, 62 long time2 = getTime() ; System.out.println(time2-time1); } }
在main方法中,调用各方法之后,有五组数据,分辨是我5次读写文件测试出来的时间(毫秒)。

关于Java.nio 请参考:http://www.iteye.com/topic/834447

付我个人测试:

[java] view plain copy
public static void main(String args[]) {
long time1 = getTime() ;
// readFileByByte(FILE_PATH); //2338,2286
// readFileByCharacter(FILE_PATH);//160,162,158
// readFileByLine(FILE_PATH); //46,51,57
// readFileByBybeBuffer(FILE_PATH);//19,18,17
// readFileByBybeBuffer(FILE_PATH);//2048: 11,13
// readFileByBybeBuffer(FILE_PATH);//1024*100 100k,711k: 6,6
// readFileByBybeBuffer(FILE_PATH);//1024*100 100k,1422k: 7
// readFileByBybeBuffer(FILE_PATH);//1024*100 100k,9951k: 49,48
// readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,711k: 7,7
// readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,1422k: 7,8
// readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,9951k: 48,49
// readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,711k: 21,13,17
// readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,1422k: 16,17,14,15
// readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,9951k:64,60

    long time2 = getTime() ;      System.out.println(time2-time1);  }  

public static void main(String args[]) { long time1 = getTime() ; // readFileByByte(FILE_PATH); //2338,2286 // readFileByCharacter(FILE_PATH);//160,162,158 // readFileByLine(FILE_PATH); //46,51,57 // readFileByBybeBuffer(FILE_PATH);//19,18,17 // readFileByBybeBuffer(FILE_PATH);//2048: 11,13 // readFileByBybeBuffer(FILE_PATH);//1024*100 100k,711k: 6,6 // readFileByBybeBuffer(FILE_PATH);//1024*100 100k,1422k: 7 // readFileByBybeBuffer(FILE_PATH);//1024*100 100k,9951k: 49,48 // readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,711k: 7,7 // readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,1422k: 7,8 // readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,9951k: 48,49 // readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,711k: 21,13,17 // readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,1422k: 16,17,14,15 // readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,9951k:64,60 long time2 = getTime() ; System.out.println(time2-time1); }