Java中的字元流
零、前言
1.字元流只能操作文字
2.本質底層依然是使用位元組操作,只不過坐了一層封裝
3.字元流是由Java虛擬機器將位元組轉化為2個位元組的Unicode字元為單位的字元而成的,對多國語言支援性比較好
一、字元流之FileWriter和FileReader
1.字元流之FileWriter的使用
注:new FileWriter(fileName,true) 追加模式新增資料
FileWriter fileWriter = null; try { String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\FileWriter.txt"; //1.建立一個輸出流--寫出檔案:需明確被操作檔案----檔案不存在,會自動建立檔案(同名覆蓋) fileWriter = new FileWriter(fileName); //2.寫入資料 fileWriter.write("Line1 第一行\r\n"); //3.重新整理流中的緩衝 fileWriter.flush(); fileWriter.write("Line2 第二行"); //獲取檔案編碼格式 System.out.println(fileWriter.getEncoding());//UTF8 } catch (IOException e) { e.printStackTrace(); } finally { //4.關閉流也會重新整理緩衝 try { //不為空,才能關閉流 if (fileWriter != null) { fileWriter.close(); } } catch (IOException e) { e.printStackTrace(); } }

FileWriter.png
2.字元流之FileReader的使用
注:為了簡單起見,將FileWriter.txt中的 Line2 第二行
刪除
public class Client { public static void main(String[] args) { String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\FileWriter.txt"; try { //1.建立一個輸入流--讀取檔案 FileReader fileReader = new FileReader(fileName); //2.讀取字元 //readOneByOne(fileReader);//一個一個讀 //readOneByWhile(fileReader);//迴圈一個一個讀 //readByCharArray(fileReader);//字元陣列讀取 //readByCharArrayByWhile(fileReader);///字元陣列迴圈讀取 fileReader.close(); } catch (IOException e) { e.printStackTrace(); } }
1).read()方法,一次讀一個字元
private static void readOneByOne(FileReader fileReader) throws IOException { int ch1 = fileReader.read(); System.out.println(ch1 + "=" + (char) ch1);//76=L int ch2 = fileReader.read(); System.out.println(ch2 + "=" + (char) ch2);//105=i int ch3 = fileReader.read(); System.out.println(ch3 + "=" + (char) ch3);//110=n int ch4 = fileReader.read(); System.out.println(ch4 + "=" + (char) ch4);//101=e int ch5 = fileReader.read(); System.out.println(ch5 + "=" + (char) ch5);//49=1 int ch6 = fileReader.read(); System.out.println(ch6 + "=" + (char) ch6);//32= int ch7 = fileReader.read(); System.out.println(ch7 + "=" + (char) ch7);//31532=第 int ch8 = fileReader.read(); System.out.println(ch8 + "=" + (char) ch8);//19968=一 int ch9 = fileReader.read(); System.out.println(ch9 + "=" + (char) ch9);//34892=行 int ch10 = fileReader.read(); System.out.println(ch10 + "=" + (char) ch10);//-1 //結束標誌 }

read.png
2).迴圈讀取
可見一個一個讀十分麻煩,既然有結束標識,每次read()都會走到下一個位置,很像迭代器模式
private static void readOneByWhile(FileReader fileReader) throws IOException { int ch = 0; while ((ch = fileReader.read()) != -1) { System.out.println(ch + "=" + (char) ch); } }
結果
76=L 105=i 110=n 101=e 49=1 32= 31532=第 19968=一 34892=行
3).使用字元陣列讀取
private static void readByCharArray(FileReader fileReader) throws IOException { //字元陣列 char[] buf = new char[8]; int len = fileReader.read(buf); System.out.println("len=" + len + "---->" + new String(buf)); //len=8---->Line1 第一 char[] buf2 = new char[8]; int len2 = fileReader.read(buf2); System.out.println("len=" + len2 + "---->" + new String(buf2)); //len=3---->行\r\n char[] buf3 = new char[8]; int len3 = fileReader.read(buf3); System.out.println("len=" + len3 + "---->" + new String(buf3)); //len=-1---->讀完後len為-1 }
4).使用字元陣列迴圈讀取
private static void readByCharArrayByWhile(FileReader fileReader) throws IOException { //字元陣列迴圈讀取 char[] buf = new char[8]; int len = 0; while ((len = fileReader.read(buf)) != -1) { System.out.println(new String(buf, 0, len)); //Line1 第一 //行 } }

read.png
二、使用字元流FileWriter和FileReader拷貝檔案
/** * 作者:張風捷特烈 * 時間:2018/10/9 0009:12:47 * 郵箱:[email protected] * 說明:將 I:\Java\Base\Thinking\src\IOTest\Activity.md *拷貝到 F:\javaTest\IO 資料夾中 */ public class Copy { public static void main(String[] args) { FileWriter fileWriter = null; FileReader fileReader = null; try { //建立一個輸出流--寫出檔案:到F:\javaTest\IO\Activity.md fileWriter = new FileWriter("F:\\javaTest\\IO\\Activity.md"); //建立一個輸入流--讀取檔案:I:\Java\Base\Thinking\src\IOTest\Activity.md fileReader = new FileReader("I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md"); int len = 0;//讀取的長度 char[] buf = new char[1024];//2K的字元陣列 while ((len = fileReader.read(buf)) != -1) { fileWriter.write(buf, 0, len);//寫有效個字元 } } catch (IOException e) { throw new RuntimeException("讀取失敗"); }finally { try {//關閉輸入流 if (fileReader != null) { fileReader.close(); } } catch (IOException e) { e.printStackTrace(); } try {//關閉輸出流 if (fileWriter != null) { fileWriter.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
三、字元緩衝:BufferedWriter和BufferedReader
將字元讀入記憶體緩衝區,避免頻繁執行讀寫操作,提高流的操作效率 預設字元陣列緩衝區大小:8192 (即16K的緩衝)
1.BufferedWriter:快取寫出
BufferedWriter bfw = null; try { String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\BufferedWriter.txt"; //1.建立一個輸出流--寫出檔案:需明確被操作檔案----檔案不存在,會自動建立檔案(同名覆蓋) bfw = new BufferedWriter(new FileWriter(fileName)); //2.寫入資料 bfw.write("Line1 第一行"); bfw.newLine();//換行 BufferedWriter特有方法,可區分不同平臺換行 //3.重新整理流中的緩衝 bfw.flush(); bfw.write("Line2 第二行"); } catch (IOException e) { e.printStackTrace(); } finally { //4.關閉流也會重新整理緩衝 try { //不為空,才能關閉流 if (bfw != null) { bfw.close(); } } catch (IOException e) { e.printStackTrace(); } }
2.BufferedReader:快取讀取
public static void main(String[] args) { String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md"; try { //1.建立一個輸入流--讀取檔案 BufferedReaderbfr= new BufferedReader(new FileReader(fileName)); //2.讀取字元 //讀取一行:BufferedReader特有方法 String line = null; while ((line = bfr.readLine()) != null) { System.out.println(line); } bfr.close(); } catch (IOException e) { e.printStackTrace(); } }
四、效率測試
通過讀取一個1275K的檔案看時間消耗情況
/** * 一個一個字元讀取測試 * * @param fileName * @return */ private static String readOneByOne(String fileName) { FileReader fileReader = null; try { StringBuilder sb = new StringBuilder(); fileReader = new FileReader(fileName); int ch = 0; while ((ch = fileReader.read()) != -1) { sb.append(new String((new char[]{(char) ch}))); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { if (fileReader != null) { fileReader.close(); } } catch (IOException e) { e.printStackTrace(); } } }
/** * 字元陣列效率測試 * * @param fileName * @return */ private static String readByArray(String fileName) { FileReader fileReader = null; try { StringBuilder sb = new StringBuilder(); fileReader = new FileReader(fileName); int len = 0; char[] buf = new char[1024]; while ((len = fileReader.read(buf)) != -1) { sb.append(new String(buf, 0, len)); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { if (fileReader != null) { fileReader.close(); } } catch (IOException e) { e.printStackTrace(); } } }
/** * BufferedReader效率測試 * * @param fileName * @return */ private static String readByBuffer(String fileName) { BufferedReader bfr = null; try { StringBuilder sb = new StringBuilder(); bfr = new BufferedReader(new FileReader(fileName)); String line = null; while ((line = bfr.readLine()) != null) { sb.append(line); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { if (bfr != null) { bfr.close(); } } catch (IOException e) { e.printStackTrace(); } } }
\ | 一個字元 | 字元陣列 | BufferedReader |
---|---|---|---|
耗時 | 0.2798秒 | 0.1043秒 | 0.1165秒 |
後記:捷文規範
1.本文成長記錄及勘誤表
專案原始碼 | 日期 | 備註 |
---|---|---|
V0.1--無 | 2018-10-9 | ofollow,noindex">Java中的字元流 |
V0.2--無 | - | - |
2.更多關於我
筆名 | 微信 | 愛好 | |
---|---|---|---|
張風捷特烈 | 1981462002 | zdl1994328 | 語言 |
我的github | 我的簡書 | 我的CSDN | 個人網站 |
3.宣告
1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大程式設計愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這裡,我在此感謝你的喜歡與支援