Java學習之IO流上(字符流: FileReader FileWriter BuffereedReader BufferedWriter 字節流:FileInputStream FileOutputStream BufferedInputStream BufferedOutputS)


 

IO流

1. IO流:用於處理設備上的數據。

設備:硬盤,內存,鍵盤錄入。

2. IO有具體的分類:

(1)根據處理的數據類型不同:字節流和字符流。

(2)根據流向不同:輸入流和輸出流。

字符流的由來:

因為文件編碼的不同,而有了對字符進行高效操作的字符流對象。

原理:其實就是基於字節流讀取字節時,去查了指定的碼表。

字節流和字符流的區別:

(1)字節流讀取的時候,讀到一個字節就返回一個字節。

字符流使用了字節流讀到一個或多個字節(中文對應的字節數是兩個,在UTF-8碼表中是3個字節)時,先去查指定的編碼表,將查到的字符返回。

(2)字節流可以處理所有類型數據,如MP3,圖片,avi。而字符流只能處理字符數據。

結論:只要是處理純文本數據,就要優先考慮使用字符流,除此之外都要用字節流。

 

 

IO的體系,所具備的基本功能就有兩個:讀和寫。

1.字節流:InputStream(讀),OutputStream(寫)。

2.字符流:Reader(讀),Writer(寫)。

 

一.字符流:

Reader  

|--InputStreamReader  

   |--FileReader:專門用於處理文件的字符讀取流對象。  

Writer

 |--OutputStreamWriter  

   |--FileWriter:專門用於處理文件的字符寫入流對象

 

 

Reader中的常見的方法:  

1. int read():  

   讀取一個字符。返回的是讀到的那個字符。如果讀到流的末尾,返回-1.  

2. int read(char[]):    

  將讀到的字符存入指定的數組中,返回的是讀到的字符個數,也就是往數組里裝的元素的個數。如果讀到流的末尾,返回-1.  

3. close():    

  讀取字符其實用的是window系統的功能,就希望使用完畢后,進行資源的釋放。

 

 

Writer中的常見的方法:  

1,write(ch): 將一個字符寫入到流中。  

2,write(char[]): 將一個字符數組寫入到流中。

3,write(String): 將一個字符串寫入到流中。  

4,flush():刷新流,將流中的數據刷新到目的地中,流還存在。  

5,close():關閉資源:在關閉前會先調用flush(),刷新流中的數據去目的地。然流關閉。

 

FileWriter:  

該類沒有特有的方法。只有自己的構造函數。  

該類特點在於,  

1,用於處理文本文件。  

2,該類中有默認的編碼表,  

3,該類中有臨時緩沖。

     

構造函數:在寫入流對象初始化時,必須要有一個存儲數據的目的地。

  FileWriter(String filename):   該構造函數做了什么事情呢?  

1,調用系統資源。  

2,在指定位置,創建一個文件。  

 注意:如果該文件已存在,將會被覆蓋。  

FileWriter(String filename,boolean append):  

   該構造函數:當傳入的boolean類型值為true時,會在指定文件末尾處進行數據的續寫。

 

FileReader:  

1,用於讀取文本文件的流對象。  

2,用於關聯文本文件。

 

 構造函數:在讀取流對象初始化的時候,必須要指定一個被讀取的文件。    

如果該文件不存在會發生FileNotFoundException.  

FileReader(String filename);

 

對於讀取或者寫入流對象的構造函數,以及讀寫方法,還有刷新關閉功能都會拋出IOException或其子類。

所以都要進行處理,或者throws拋出,或者try、catch處理。

 

將文本數據存儲到一個文件:

 1 import java.io.*;
 2 public class TestFileWriter1 {
 3     public static void main(String[] args){
 4         FileWriter fw=null;
 5         try{
 6             fw=new FileWriter("D:\\JAVA練習代碼\\123.txt");
 7             fw.write("abcdec");
 8             fw.flush();
 9             fw.write("kkkk");
10         }catch(IOException e){
11             System.out.println(e.toString());
12         }
13         finally{
14             if(fw!=null)
15                 try{
16                     fw.close();
17                 }catch (IOException e) {
18                     System.out.println("close"+e.toString());
19                 }
20         }
21     }
22 }

 

 

另一個小細節:  

當指定絕對路徑時,定義目錄分隔符有兩種方式:

1,反斜線 但是一定要寫兩個。\\  new FileWriter("c:\\demo.txt");

2,斜線  /  寫一個即可。 new FileWriter("c:/demo.txt");

 

讀一個字符就存入字符數組里,讀完1Kb再打印。

 1 import java.io.*;
 2 public class TestFileReader1 {
 3     public static void main(String[] args){
 4         FileReader fr=null;
 5         try{
 6             fr=new FileReader("D:\\JAVA練習代碼\\abc.txt");
 7             char[]buf=new char[1024];    //該長度通常都是1024的整數倍
 8             int len=0;
 9             while((len=fr.read(buf))!=-1){
10                 System.out.println(new String(buf,0,len));
11             }
12         }catch(IOException e){
13             System.out.println(e);
14         }
15         finally{
16             if(fr!=null){
17                 try{
18                     fr.close();
19                 }catch(IOException e){
20                     System.out.println("close"+e);
21                 }
22             }
23         }
24     }
25 }

 

 

 

 

字符流的緩沖區:

 

緩沖區的出現提高了對流的操作效率。

原理:其實就是將數組進行封裝。

對應的對象:

BufferedWriter:

  特有方法:

    newLine():跨平台的換行符。

BufferedReader:

  特有方法:

    readLine():一次讀一行,到行標記時,將行標記之前的字符數據作為字符串返回。當讀到末尾時,返回null。

 

使用緩沖區對象時,要明確,緩沖的存在是為了增強流的功能而存在,所以在簡歷緩沖區對象時,要現有流對象存在。

其實緩沖內部就是在使用流對象的方法,只不過加入了數組對數據進行了臨時存儲,為了提高操作數據的效率。

 

代碼上的體現:

寫入緩沖區對象:

//建立緩沖區對象必須把流對象作為參數傳遞給緩沖區的構造函數。

BufferedWriter bw=new BufferedWriter(new FileWriter(“abc.txt”));

bw.write("abce");//將數據寫入到了緩沖區。

bw.flush();//對緩沖區的數據進行刷新。將數據刷到目的地中。

bw.close();//關閉緩沖區,其實關閉的是被包裝在內部的流對象。

讀取緩沖區對象:

BufferedReader br=new BufferedReader(new FileReader("abc.txt"));

String s=null;

 

 1 import java.io.*;
 2 public class TestBufferStream {
 3     public static void main(String[] args){
 4         try{
 5             BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\Java練習代碼\\abc.txt"));
 6             BufferedReader br=new BufferedReader(new FileReader("D:\\Java練習代碼\\abc.txt"));
 7             String s=null;
 8             for(int i=1;i<=100;i++){
 9                 s=String.valueOf(Math.random());
10                 bw.write(s);
11                 bw.newLine();
12             }
13             bw.flush();
14             while((s=br.readLine())!=null){
15                 System.out.println(s);
16             }
17             bw.close();
18             br.close();
19         }catch (IOException e){
20             e.printStackTrace();
21         }    
22     }
23 }

 

 二.字節流:

抽象基類:InputStream,OutputStream。

字節流可以操作任何數據。

注意:字符流使用的數組是字符數組,char[] chs ;

   字節流使用的數組是字節數組,byte[] bt ;

FileOutputStream fos=new FileOutputStream(“a.txt”);

fos.write("abcde"); //直接將數據寫入到了目的地。

fos.close();//只關閉資源。

FileInputSteam fls=new FileInputStream("a.txt");

//fis.available();//獲取關聯的文件字節數。如果文件體積不大,可以這樣操作。

byte[]buf=new byte[fis.available()];//創建一個剛剛好的緩沖區。//但是這有一個弊端,就是文件過大,大小超出Jvm的內容空間時,會內存溢出。

fis.read(buf);

System.out.println(new String(buf));

 

例子:

  需求:copy一個圖片。

BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("1.jpg"));

BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("2.jpg"));

int by=0;

while(by=bufis.read()!=-1){

  bufos.write(by);

  bufos.newLine();

}

bufis.close();

bufos.close();

 

小結:

目前學習的流對象:

字符流: FileReader  FileWriter  BuffereedReader  BufferedWriter

字節流:FileInputStream  FileOutputStream   BufferedInputStream  BufferedOutputStream

 

補充:

1.字節流的read()方法讀取的是一個字節。為什么返回的不是byte類型,而是int類型呢?

因為read方法讀到末尾時返回的是-1,而在所操作的數據中很容易出現連續多個1的情況,而連續讀到8個1,就是-1,導致讀取會提前停止。所以將讀到的一個字節提升為一個int類型的數值,但是只保留原字節,並在剩余二進制位補0。

具體操作是:byte&255 or byte&0xff

2.對於write方法,可以一次寫入一個字節,但接收的是一個int類型數值。只寫入該int類型的數值的最低一個字節(8位)。

簡單說:read方法對讀到的數據進行提升,write對操作的數據進行轉換。

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM