IO流
IO流
使用IO流技術讀取檔案的內容資料。
IO流解決問題: 解決裝置與裝置之間的資料傳輸問題。 記憶體--->硬碟 硬碟--->記憶體
一、IO流分類
1.按照資料的流向劃分:
- 輸入流
- 輸出流
判斷是輸入流還是輸出流:
以當前程式作為參照物,觀察資料是流入還是流出,如果是流入則是輸入流,如果是流出則是輸出流。

判斷輸入輸出流.png
2.按照處理的單位劃分:
- 位元組流:位元組流讀取得都是檔案中二進位制資料,讀取到二進位制資料不會經過任何的處理。
- 字元流:字元流讀取的資料是以字元為單位的 。 字元流也是讀取檔案中的二進位制資料,但是會把這些二進位制資料轉換成我們能識別的字元。
字元流 = 位元組流 + 解碼
二、位元組流
位元組流:
輸入位元組流 -----------| InputStream 輸入位元組流的基類抽象類 ----------------| FileInputStream 讀取檔案資料的輸入位元組流。 ----------------| BufferedInputStream 緩衝輸入位元組流緩衝輸入位元組流出現的目的: 為了提高讀取檔案資料的效率。 該類內部維護了一個8kb位元組陣列 輸出位元組流: ---------| OutputStream 輸出位元組流的基類。抽象類 --------------| FileOutStream向檔案輸出資料的輸出位元組流。 --------------| BufferedOutputStream 緩衝輸出位元組流。該類出現的目的是為了提高寫資料的效率 。 該類內部也是維護了一個8kb的陣列 當呼叫其write方法的時候資料預設是向它內部的陣列中儲存的,只有呼叫flush方法或者是close方法或者是8kb的位元組陣列儲存滿資料的時候才會真正的向硬碟輸出。
1.輸入位元組流
--------| InputStream 所有輸入位元組流的基類抽象類 ------------| FileInputStream讀取檔案資料的輸入位元組流
使用FileInputStream讀取檔案資料的步驟:
- 找到目標檔案
- 建立資料的輸入通道。
- 讀取檔案中的資料。
- 關閉資源.
public class Demo1 { public static void main(String[] args) throws IOException { readTest4(); } //方式4:使用緩衝陣列配合迴圈一起讀取。28 public static void readTest4() throws IOException{ long startTime = System.currentTimeMillis(); //找到目標檔案 File file = new File("F:\\study\\1.jpg"); //建立資料的輸入通道 FileInputStream fileInputStream = new FileInputStream(file); //建立緩衝陣列配合迴圈讀取檔案的資料。 int length = 0; //儲存每次讀取到的位元組個數。 byte[] buf = new byte[1024]; //儲存讀取到的資料緩衝陣列 的長度一般是1024的倍數,因為與計算機的處理單位。理論上緩衝陣列越大,效率越高 while((length = fileInputStream.read(buf))!=-1){ // read方法如果讀取到了檔案的末尾,那麼會返回-1表示。 System.out.print(new String(buf,0,length)); } //關閉資源 fileInputStream.close(); long endTime = System.currentTimeMillis(); System.out.println("讀取的時間是:"+ (endTime-startTime)); //446 } //方式3:使用緩衝 陣列 讀取。缺點: 無法讀取完整一個檔案的資料。12G public static void readTest3() throws IOException{ //找到目標檔案 File file = new File("F:\\a.txt"); //建立資料的輸入通道 FileInputStream fileInputStream = new FileInputStream(file); //建立緩衝位元組陣列,讀取檔案的資料。 byte[] buf = new byte[1024]; // 如果使用read讀取資料傳入位元組陣列,那麼資料是儲存到位元組陣列中的, //而這時候read方法的返回值是表示的是本次讀取了幾個位元組資料到位元組陣列中。 int length = fileInputStream.read(buf); System.out.println("length:"+ length); //使用位元組陣列構建字串 String content = new String(buf,0,length); System.out.println("內容:"+ content); //關閉資源 fileInputStream.close(); } //方式2 : 使用迴圈讀取檔案的資料 public static void readTest2() throws IOException{ long startTime = System.currentTimeMillis(); //找到目標檔案 File file = new File("F:\\study\\1.jpg"); //建立資料的輸入通道 FileInputStream fileInputStream = new FileInputStream(file); //讀取檔案的資料 int content = 0; //宣告該變數用於儲存讀取到的資料 while((content = fileInputStream.read())!=-1){ System.out.print((char)content); } //關閉資源 fileInputStream.close(); long endTime = System.currentTimeMillis(); System.out.println("讀取的時間是:"+ (endTime-startTime)); //446 } //讀取的方式一缺陷: 無法讀取完整一個檔案 的資料. public static void readTest1() throws IOException{ //1. 找到目標檔案 File file = new File("F:\\a.txt"); //建立資料的輸入通道。 FileInputStream fileInputStream = new FileInputStream(file); //讀取檔案中的資料 int content = fileInputStream.read(); // read() 讀取一個位元組的資料,把讀取的資料返回。 System.out.println("讀到的內容是:"+ (char)content); //關閉資源實際上就是釋放資源。 fileInputStream.close(); } }
2.輸出位元組流
輸出位元組流:
--------| OutputStream 是所有輸出位元組流 的父類。抽象類 -----------| FileOutStream 向檔案輸出資料的輸出位元組流。
FileOutputStream寫出檔案的步驟:
- 找到目標檔案
- 建立資料的輸出通道。
- 把資料轉換成位元組陣列寫出。
- 關閉資源
public class Demo1 { public static void main(String[] args) throws IOException { writeTest3(); } //使用位元組陣列把資料寫出。 public static void writeTest3() throws IOException{ //找到目標檔案 File file = new File("F:\\b.txt"); //建立資料輸出通道 FileOutputStream fileOutputStream = new FileOutputStream(file); //把資料寫出。 String data = "abc"; byte[] buf = data.getBytes(); fileOutputStream.write(buf, 0, 3); // 0 從位元組陣列的指定索引值開始寫, 2:寫出兩個位元組。 //關閉資源 fileOutputStream.close(); } //使用位元組陣列把資料寫出。 public static void writeTest2() throws IOException{ //找到目標檔案 File file = new File("F:\\b.txt"); //建立資料輸出通道 FileOutputStream fileOutputStream = new FileOutputStream(file,true); //把資料寫出。 String data = "\r\nhello world"; fileOutputStream.write(data.getBytes()); //關閉資源 fileOutputStream.close(); } //每次只能寫一個位元組的資料出去。 public static void writeTest1() throws IOException{ //找到目標檔案 File file = new File("F:\\b.txt"); //建立資料的輸出通道 FileOutputStream fileOutputStream = new FileOutputStream(file); //把資料寫出 fileOutputStream.write('h'); fileOutputStream.write('e'); fileOutputStream.write('l'); fileOutputStream.write('l'); fileOutputStream.write('o'); //關閉資源 fileOutputStream.close(); } }
FileOutputStream要注意的細節:
- 使用FileOutputStream的時候,如果目標檔案不存在,那麼會自動建立目標檔案物件。
- 使用FileOutputStream寫資料的時候,如果目標檔案已經存在,那麼會先清空目標檔案中的資料,然後再寫入資料。
3.使用FileOutputStream寫資料的時候, 如果目標檔案已經存在,需要在原來資料基礎上追加資料的時候應該使用new FileOutputStream(file,true)建構函式,第二引數為true。
4.使用FileOutputStream的write方法寫資料的時候,雖然接收的是一個int型別的資料,但是真正寫出的只是一個位元組的資料,只是把低八位的二進位制資料寫出,其他二十四位資料全部丟棄。
public class Demo2 { public static void main(String[] args) throws IOException { readTest(); } public static void readTest() throws IOException{ //找到目標檔案 File file = new File("F:\\hcx.txt"); //建立資料的輸入通道 FileInputStream fileInputStream = new FileInputStream(file); //建立緩衝輸入讀取檔案資料 byte[] buf = new byte[4]; //讀取檔案資料 int length = fileInputStream.read(buf); System.out.println("位元組陣列的內容:"+ Arrays.toString(buf)); //關閉資源 fileInputStream.close(); } public static void writeTest() throws FileNotFoundException, IOException { //找到目標檔案 File file = new File("F:\\hcx.txt"); //建立資料的輸出通道 FileOutputStream fileOutputStream = new FileOutputStream(file); //把資料寫出 fileOutputStream.write(511); //關閉資源 fileOutputStream.close(); } }
拷貝一張圖片:
public class CopyImage { public static void main(String[] args) throws IOException { //找到目標檔案 File inFile = new File("F:\\1.jpg"); File destFile = new File("E:\\1.jpg"); //建立資料的輸入輸出通道 FileInputStream fileInputStream = newFileInputStream(inFile); FileOutputStream fileOutputStream = new FileOutputStream(destFile); //追加資料.... //每新建立一個FileOutputStream的時候,預設情況下FileOutputStream 的指標是指向了檔案的開始的位置。 //每寫出一次,指標都會出現相應移動。 //建立緩衝資料,邊讀邊寫 byte[] buf = new byte[1024]; int length = 0 ; while((length = fileInputStream.read(buf))!=-1){ fileOutputStream.write(buf,0,length); } //關閉資源 原則: 先開後關,後開先關。 fileOutputStream.close(); fileInputStream.close(); } }
三、IO異常的處理
在發生異常時,要阻止後面的程式碼執行,並且要通知呼叫者這裡出錯了:
通過在catch塊中丟擲執行時異常,並把異常傳遞過去,丟擲執行時異常,方法上可以宣告也可以不宣告,呼叫者可以處理也可以不處理,把IOException傳遞給RuntimeException包裝一層,然後再丟擲,這樣子做的目的是為了讓呼叫者使用變得更加靈活。
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import javax.management.RuntimeErrorException; /* IO異常 的處理 */ public class Demo1 { public static void main(String[] args) { //readTest(); copyImage(); } // 拷貝圖片 public static void copyImage() { FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { // 找到目標檔案 File inFile = new File("F:\\1.jpg"); File outFile = new File("E:\\1.jpg"); // 建立輸入輸出通道 fileInputStream = new FileInputStream(inFile); fileOutputStream = new FileOutputStream(outFile); // 建立緩衝陣列,邊讀邊寫 byte[] buf = new byte[1024]; int length = 0; while ((length = fileInputStream.read(buf)) != -1) { fileOutputStream.write(buf, 0, length); } } catch (IOException e) { System.out.println("拷貝圖片出錯..."); throw new RuntimeException(e); } finally { // 關閉資源 try { if (fileOutputStream != null) { fileOutputStream.close(); System.out.println("關閉輸出流物件成功..."); } } catch (IOException e) { System.out.println("關閉輸出流資源失敗..."); throw new RuntimeException(e); } finally { if (fileInputStream != null) { try { fileInputStream.close(); System.out.println("關閉輸入流物件成功..."); } catch (IOException e) { System.out.println("關閉輸入流物件失敗..."); throw new RuntimeException(e); } } } } } public static void readTest() { FileInputStream fileInputStream = null; try { // 找到目標檔案 File file = new File("F:\\a.txt"); // 建立資料輸入通道 fileInputStream = new FileInputStream(file); // 建立緩衝陣列讀取資料 byte[] buf = new byte[1024]; int length = 0; while ((length = fileInputStream.read(buf)) != -1) { System.out.print(new String(buf, 0, length)); } } catch (IOException e) { /* * //處理的程式碼... 首先你要阻止後面的程式碼執行,而且要需要通知呼叫者這裡出錯了... throw new * RuntimeException(e); * //把IOException傳遞給RuntimeException包裝一層,然後再丟擲,這樣子做的目的是 * 為了讓呼叫者使用變得更加靈活。 */ System.out.println("讀取檔案資源出錯...."); throw new RuntimeException(e); } finally { try { if (fileInputStream != null) { fileInputStream.close(); System.out.println("關閉資源成功..."); } } catch (IOException e) { System.out.println("關閉資源失敗..."); throw new RuntimeException(e); } } } }
四、緩衝位元組流
緩衝輸入位元組流物件,可以更高效率讀取檔案。
1.緩衝輸入位元組流
輸入位元組流體系:
----| InputStream輸入位元組流的基類。 抽象 ----------| FileInputStream 讀取檔案資料的輸入位元組流 ----------| BufferedInputStream 緩衝輸入位元組流緩衝輸入位元組流的出現主要是為了提高讀取檔案資料的效率。(其實該類內部只不過是維護了一個8kb的位元組陣列而已。)
注意: 凡是緩衝流都不具備讀寫檔案的能力。
使用BufferedInputStream的步驟:
- 找到目標檔案
- 建立資料的輸入通道
- 建立緩衝輸入位元組流流
- 關閉資源
注意:有緩衝流時,只需要關閉緩衝流,因為呼叫BufferedInputStream的close方法實際上關閉的是FileinputStream.
BufferedInputStream出現的目的是了提高讀取檔案的效率,但是BufferedInputStream的read方法每次讀取一個位元組的資料,而FileInputStreram每次也是讀取一個位元組的資料,那麼BufferedInputStream效率高的原因是什麼?
緩衝類內部維護了一個8kb的位元組陣列,而BufferedInputStream的read()方法如下:
public synchronized int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) return -1; } return getBufIfOpen()[pos++] & 0xff; }
count:目前緩衝陣列中儲存了幾個位元組的資料
pos:當前已經讀取到了第幾個位元組(指標)
第一次的時候,count為0,pos也為0,呼叫fill()方法,使用內部維護的緩衝陣列去讀取檔案資料,一次最多讀取8kb的位元組資料到緩衝陣列中。最後從位元組陣列中取出資料並返回。當第二次往後呼叫時,每次都從位元組陣列中取出資料並返回,直到取完之後,再次填充。而fileInputStream每次都是從硬碟中讀取資料。
使用bufferedInputStream和自己建立一個8kb的位元組陣列,兩者的效率是一樣的。嚴格意義上說,自己建立陣列效率更高一些,因為沒有了判斷的步驟。
public class Demo1 { public static void main(String[] args) throws IOException { readTest2(); } public static void readTest2() throws IOException{ //找到目標檔案 File file = new File("F:\\a.txt"); FileInputStream fileInputStream= new FileInputStream(file); //建立BufferedInputStream的時候需要傳入fileInputStream:BufferedInputStream本身不具備讀檔案的能力, //需要藉助fileInputStream來讀取檔案的資料。 BufferedInputStream bufferedInputStream= new BufferedInputStream(fileInputStream); bufferedInputStream.read(); //讀取檔案資料 int content = 0 ; //BufferedInputStream出現 的目的是了提高讀取檔案的效率,但是BufferedInputStream的read方法每次讀取一個位元組的資料 //而FileInputStreram每次也是讀取一個位元組的資料,那麼BufferedInputStream為什麼效率更高 while((content = fileInputStream.read())!=-1){ System.out.print((char)content); } //關閉資源 bufferedInputStream.close();//呼叫BufferedInputStream的close方法實際上關閉的是FileinputStream. } //讀取檔案的時候都是使用緩衝陣列讀取。效率會更加高(推薦) public static void readTest() throws IOException{ File file = new File("F:\\a.txt"); //建立陣列通道 FileInputStream fileInputStream = new FileInputStream(file); //建立緩衝陣列讀取資料 byte[] buf = new byte[1024*8]; int length = 0; while((length = fileInputStream.read(buf))!=-1){ System.out.print(new String(buf,0,length)); } //關閉資源 fileInputStream.close(); } }
2.緩衝輸出位元組流
輸出位元組流
--------| OutputStream所有輸出位元組流的基類抽象類 ------------| FileOutputStream 向檔案 輸出資料 的輸出位元組流 ------------| Bufferedoutputstream緩衝輸出位元組流BufferedOutputStream出現的目的是為了提高寫資料的效率。 (內部也是維護了一個8kb的位元組陣列)
BufferedOutputStream要注意的細節:
- 使用BufferedOutputStream寫資料的時候,它的write方法是是先把資料寫到它內部維護的位元組陣列中。
- 使用BufferedOutputStream寫資料的時候,它的write方法是是先把資料寫到它內部維護的位元組陣列中,如果需要把資料真正的寫到硬碟上面,需要呼叫flush方法或者是close方法,當內部維護的位元組陣列已經填滿資料的時候,會自動把資料刷出去。
public class Demo2 { public static void main(String[] args) throws IOException { //找到目標檔案 File file = new File("F:\\a.txt"); //建立資料的輸出通道 FileOutputStreamfileOutputStream = new FileOutputStream(file); //建立緩衝輸出位元組流物件 BufferedOutputStream bufferedOutputStream= new BufferedOutputStream(fileOutputStream); //把資料寫出 bufferedOutputStream.write("hello world".getBytes()); //把緩衝陣列中內部的資料寫到硬碟上面。 //bufferedOutputStream.flush(); bufferedOutputStream.close(); } }
注意:使用read方法如果傳入了緩衝陣列,內容是儲存到了緩衝陣列中,返回值返回的是儲存到緩衝陣列中的位元組個數。如果read方法沒有傳入緩衝陣列,那麼返回值是讀取到的內容。
使用緩衝輸入輸出位元組流拷貝圖片:
public class CopyImage { public static void main(String[] args) throws IOException { //找到目標檔案 FileinFile = new File("F:\\美女\\1.jpg"); File outFile = new File("E:\\1.jpg"); //建立資料輸入輸出通道 FileInputStream fileInputStream = new FileInputStream(inFile); FileOutputStream fileOutputStream = new FileOutputStream(outFile); //建立緩衝輸入輸出流 BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); //邊讀邊寫 int content = 0; // int length = bufferedInputStream.read(buf);如果傳入了緩衝陣列,內容是儲存到緩衝陣列中,返回值是儲存到緩衝陣列中的位元組個數。 while((content = bufferedInputStream.read())!=-1){ // 如果使用read方法沒有傳入緩衝陣列,那麼返回值是讀取到的內容。 bufferedOutputStream.write(content); //bufferedOutputStream.flush(); } //關閉資源 bufferedInputStream.close(); bufferedOutputStream.close(); } }
五、字元流
使用位元組流來讀寫中文都是比較麻煩的:
public class Demo1 { public static void main(String[] args) throws IOException { //writeTest(); readrTest(); } //使用位元組流讀取中文 public static void readrTest() throws IOException{ //找到目標檔案 File file = new File("F:\\a.txt"); //建立資料的輸入通道 FileInputStream fileInputStream = new FileInputStream(file); //讀取內容 //int content = 0; /*while((content = fileInputStream.read())!=-1){ //出現亂碼的原因: 一箇中文在gbk碼錶中預設是佔兩個位元組, // 目前你只讀取了一個位元組而已,所以不是一個完整的中文。 System.out.print((char)content); }*/ byte[] buf = new byte[2]; for(int i = 0 ; i < 3 ; i++){ fileInputStream.read(buf); System.out.print(new String(buf)); } //關閉資源 fileInputStream.close(); } //使用位元組流寫中文。 //位元組流之所以能夠寫中文是因為藉助了字串的getBytes方法對字串進行了編碼(字元---->數字)。 public static void writeTest() throws IOException{ //找到目標檔案 File file = new File("F:\\a.txt"); //建立資料的輸出通道 FileOutputStream fileOutputStream= new FileOutputStream(file); //準備資料,把資料寫出。 String data = "大家好"; byte[] buf = data.getBytes();//把字串轉換成位元組陣列 System.out.println("輸出的內容:"+ Arrays.toString(buf));//[-76,-13,-68,-46,-70,-61] fileOutputStream.write(buf); ///關閉資源 fileOutputStream.close(); } }
位元組流:位元組流讀取的是檔案中的二進位制資料,讀到的資料並不會幫你轉換成你看得懂的字元。
1.輸入字元流
字元流: 字元流會把讀取到的二進位制的資料進行對應的編碼與解碼工作。
字元流 = 位元組流 + 編碼(解碼)
輸入字元流:
-------| Reader 所有輸入字元流的基類。 抽象類 ----------| FileReader 讀取檔案字串的輸入字元流。 ----------| BufferedReader緩衝輸入字元流 。 緩衝輸入字元流出現的目的是為了提高讀取檔案 的效率和拓展了FileReader的功能。(其實該類內部也是維護了一個字元陣列)
注意:緩衝流都不具備讀寫檔案的能力。
public class Demo2 { public static void main(String[] args) throws IOException { readTest2(); } //使用緩衝字元陣列讀取檔案。 public static void readTest2() throws IOException{ //找到目標檔案 File file = new File("F:\\Demo1.java"); // 建立資料的輸入通道 FileReader fileReader = new FileReader(file); //建立緩衝字元陣列讀取檔案資料 char[] buf = new char[1024]; int length = 0 ; while((length = fileReader.read(buf))!=-1){ System.out.print(new String(buf,0,length)); } } public static void readTest1() throws IOException{ //找到目標檔案 File file = new File("F:\\Demo1.java"); //建立資料的輸入通道 FileReader fileReader = new FileReader(file); int content = 0 ; while((content = fileReader.read())!=-1){ //每次只會讀取一個字元,效率低。 System.out.print((char)content); } //關閉資源 fileReader.close(); } }
2.輸出字元流
輸出字元流:
------| Writer 輸出字元流的基類。抽象類 -----------| FileWriter 向檔案輸出資料的輸出字元流
FileWriter要注意的事項:
- 使用FileWriter寫資料的時候,FileWriter內部是維護了一個1024個字元陣列的,寫資料的時候會先寫入到它內部維護的字元陣列中,如果需要把資料真正寫到硬碟上,需要呼叫flush或者是close方法或者是填滿了內部的字元陣列。
- 使用FileWriter的時候,如果目標檔案不存在,那麼會自動建立目標檔案。
3.使用FileWriter的時候, 如果目標檔案已經存在了,那麼預設情況會先清空檔案中的資料,然後再寫入資料 , 如果需要在原來的基礎上追加資料,需要使用“new FileWriter(File , boolean)”的構造方法,第二引數為true。
public class Demo1 { public static void main(String[] args) throws IOException { writeTest1(); } public static voidwriteTest1() throws IOException{ //找到目標檔案 File file = new File("F:\\a.txt"); //建立資料輸出通道 FileWriter fileWriter = new FileWriter(file,true); //準備資料,把資料寫出 String data = "你好 世界"; fileWriter.write(data);//字元流具備解碼的功能。 //重新整理字元流 //fileWriter.flush(); //關閉資源 fileWriter.close(); } }
使用FileReader進行檔案的拷貝沒問題,但是拷貝圖片時資料會丟失,圖片損壞
public class CopyImage { public static void main(String[] args) throws IOException { File inFile = new File("F:\\1.jpg"); File outFile = new File("E:\\2.jpg"); FileReader fileReader = new FileReader(inFile); FileWriter fileWriter = new FileWriter(outFile); char[] buf = new char[1024]; int length = 0; while((length = fileReader.read(buf))!=-1) { fileWriter.write(buf,0,length); } fileWriter.close(); fileReader.close(); } }
原因:計算機中的所有資訊都是以二進位制形式進行的儲存(1010)圖片中的也都是二進位制。在讀取檔案的時候字元流自動對這些二進位制按照碼錶進行了編碼處理,但是圖片本來就是二進位制檔案,不需要進行編碼。有一些巧合在碼錶中有對應,就可以處理,並不是所有的二進位制都可以找到對應的。資訊就會丟失。所以字元流只能拷貝以字元為單位的文字檔案(以ASCII碼為例是127個,並不是所有的二進位制都可以找到對應的ASCII,有些對不上的,就會丟失資訊。)
使用字元流的應用場景: 如果是讀寫字元資料的時候則使用字元流。
使用位元組流的應用場景: 如果讀寫的資料都不需要轉換成字元的時候,則使用位元組流。
六、緩衝字元流
1.緩衝輸入字元流
輸入字元流:
-------| Reader 所有輸入字元流的基類。 抽象類 ----------| FileReader 讀取檔案字串的輸入字元流。 ----------| BufferedReader緩衝輸入字元流 。緩衝輸入字元流出現的目的是為了提高讀取檔案的效率和拓展了FileReader的功能。(該類內部也是維護了一個字元陣列)
注意:緩衝流都不具備讀寫檔案的能力。
public class Demo1 { public static void main(String[] args) throws IOException { //readTest1(); File file= new File("F:\\Demo1.java"); //建立資料的輸入通道。 FileReader fileReader = new FileReader(file); String line =null; while((line = myReadLine(fileReader))!=null){ System.out.println(line); } } //實現readLine方法。 public static String myReadLine(FileReader fileReader) throws IOException{ //建立一個字串緩衝類物件 StringBuilder sb = new StringBuilder();//StringBuilder主要是用於儲存讀取到的資料 int content = 0 ; while((content = fileReader.read())!=-1){ if(content=='\r'){ continue; }else if(content=='\n'){ break; }else{ //普通字元 sb.append((char)content); } } //代表已經讀取完畢了。 if(content ==-1){ return null; } return sb.toString(); } public static void readTest1() throws IOException{ //找到目標檔案 File file= new File("F:\\a.txt"); //建立資料的輸入通道。 FileReader fileReader = new FileReader(file); //建立緩衝輸入字元流 BufferedReader bufferedReader = new BufferedReader(fileReader); //讀取資料 /*int content = bufferedReader.read();//讀到了一個字元。 讀取到的字元肯定也是從Bufferedreader內部的字元陣列中獲取的到。所以效率高。 System.out.println((char)content);*/ //使用BUfferedReader拓展的功能,readLine()一次讀取一行文字,如果讀到了檔案的末尾返回null表示。 String line =null; while((line = bufferedReader.readLine())!=null){ // 雖然readLine每次讀取一行資料,但是返回的line是不包含\r\n的 System.out.println(Arrays.toString("a".getBytes())); } //關閉資源 bufferedReader.close(); } }
2.緩衝輸出字元流
輸出字元流
----------| Writer所有輸出字元流的基類,抽象類。 --------------- | FileWriter 向檔案輸出字元資料的輸出字元流。 ----------------| BufferedWriter 緩衝輸出字元流
緩衝輸出字元流作用: 提高FileWriter的寫資料效率與拓展FileWriter的功能。
BufferedWriter內部提供了一個8192長度的字元陣列作為緩衝區,拓展了FileWriter的功能。
public class Demo2 { public static void main(String[] args) throws IOException { //找到目標檔案 File file = new File("F:\\a.txt"); //建立資料的輸出通道 FileWriter fileWriter = new FileWriter(file,true); //建立緩衝輸出流物件 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); //寫出資料 //bufferedWriter.newLine(); //newLine() 換行。 實際上就是向檔案輸出\r\n. bufferedWriter.write("\r\n"); bufferedWriter.write("我要去到蓮花山頂看燈光秀!!"); //關閉資源 bufferedWriter.flush(); //bufferedWriter.close(); } }