干Java這么久,一直在做WEB相關的項目,一些基礎類差不多都已經忘記。經常想得撿起,但總是因為一些原因,不能如願。
其實不是沒有時間,只是有些時候疲於總結,今得空,下定決心將丟掉的都給撿起來。
文件讀寫是一個在項目中經常遇到的工作,有些時候是因為維護,有些時候是新功能開發。我們的任務總是很重,工作節奏很快,快到我們不能停下腳步去總結。
文件讀寫有以下幾種常用的方法
1、字節讀寫(InputStream/OutputStream)
2、字符讀取(FileReader/FileWriter)
3、行讀取(BufferedReader/BufferedWriter)
代碼(以讀取為例):
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; /** * <b>文件讀取類</b><br /> * 1、按字節讀取文件內容<br /> * 2、按字符讀取文件內容<br /> * 3、按行讀取文件內容<br /> * @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更有效率。
經過修改之后的代碼如下:
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; /** * <b>文件讀取類</b><br /> * 1、按字節讀取文件內容<br /> * 2、按字符讀取文件內容<br /> * 3、按行讀取文件內容<br /> * * @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