抽象基類: InputStream , OutputStream。數組
字節流能夠操做任何數據。jvm
注意:字符流使用的數組時字符數組。char[] chs函數
字節流使用的數組時字節數組。byte[] bt學習
FileOutputStream fos = new FileOutputStream("a.txt");編碼
fos.write("abcde");//直接將數據寫入到了目的地。對象
fos.close();//只關閉資源。繼承
FileInputStream fis = new FileInputStream("a.txt");圖片
//fis.available();//獲取關聯的文件的字節數。內存
//若是文件體積不是很大。utf-8
//能夠這樣操做。
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.close();
bufis.close();
目前學習的流對象:
字符流:
FileReader
FileWriter
BufferedReader
BufferedWriter
字節流:
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOutputStream
字節流的read() 方法讀取一個字節。爲何返回的不是byte類型,而是int類型呢?
由於read方法讀到末尾時返回的是-1.
而在所操做的數據中很容易出現連續多個1的狀況,而連續讀到8個1,就是-1.
致使讀取會提早中止。
因此將讀到的一個字節給提高爲一個int類型的數值,可是隻保留原字節,並在剩餘二進制位補0.
具體操做是:byte&255 or byte&0xff
對於write方法,能夠一次寫入一個字節,但接收的是一個int類型數值。
只寫入該int類型的數值的最低一個字節(8位)。
簡單說:read方法對讀到的數據進行提高。write對操做的數據進行轉換。
轉換流:
特色:
1:是字節流和字符流之間的橋樑。
2:該流對象中能夠對讀取到的字節數據進行指定編碼表的編碼轉換。
何時使用呢?
1:當字節和字符之間有轉換動做時。
2:流操做的數據須要進行編碼表的指定時。
具體的對象體現:
1:InputStreamReader:字節到字符的橋樑。
2:OutputStreamWriter:字符到字節的橋樑。
這兩個流對象是字符流體系中的成員。
那麼它們有轉換做用,而自己又是字符流。因此在構造的時候,須要傳入字節流對象進來。
構造函數:
InputStreamReader(InputStream):經過該構造函數初始化,使用的是本系統默認的編碼表GBK
InputStreamReader(InputStream,String charSet):經過該構造函數初始化,能夠指定編碼表。
OutputStreamWriter(OutputStream):經過該構造函數初始化,使用的是本系統默認的編碼表GBK。
OutputStreamWriter(OutputStream,String charSet):經過該構造函數初始化,能夠指定編碼表。
操做文件的字符流對象時轉換流的子類。
Reader
--->InputStreamReader
--->FileReader
Writer
--->OutputStreamWriter
--->FileWriter
轉換流中的read方法。已經融入了編碼表,
在底層調用字節流的read方法時將獲取的一個或者多個字節數據進行臨時存儲,並去查指定的編碼表,若是編碼表沒有指定,查的是默認編碼表。那麼轉換流的read方法就能夠返回一個字符好比中文。
轉換流已經完成了編碼轉換的動做,對於直接操做的文本文件的FileReader而言,就不用在從新定義了,只要繼承該轉換流,獲取其方法,就能夠直接操做文本文件中的字符數據了。
注意:
在使用FileReader操做文本數據時,該對象使用的是默認的編碼表。若是要使用指定編碼表時,必須使用轉換流。
FileReader fr = new FileReader("a.txt");//操做a.txt中的數據使用本系統默認編碼GBK。操做a.txt中的數據使用的也是本系統默認編碼GBK。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
這兩句的代碼的意義相同。
若是a.txt中的文件中的字符數據時經過utf-8的形式編碼。
那麼在讀取時,就必須指定編碼表。
那麼轉換流必須使用。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"utf-8");
流操做的基本規律。
1:明確數據源和數據匯(數據目的)。
實際上是爲了明確輸入流仍是輸出流。
2:明確操做的數據是否時純文本數據。
實際上是爲了明確字符流仍是字節流。
數據源:鍵盤System.int , 硬盤 File 開頭的流對象,內存(數組)。
數據匯:控制檯System.out,硬盤 File 開頭的流對象 , 內存(數組)。
需求:
1:將鍵盤錄入的數據存儲到一個文件中。
數據源:System.in
既然是源,使用的就是輸入流,可用的體系有InputStream , Reader.
由於鍵盤錄入進來的必定時純文本數據,因此可使用專門操做字符數據的Reader。
發現System.in對應的流時字節讀取流。因此要將其進行轉換,將字節轉成字符便可。
因此要使用Reader體系中:InputStreamReader
接下來,是否須要提升效率呢?若是須要,那麼就加入字符流的緩衝區:BufferedReader
BufferedReader bur = new BufferedReader(new InputStreamReader(System.in));
數據匯:一個文件,硬盤。
既然時數據匯,那麼必定時輸出流,能夠用的OutputStream,Writer.
往文件中存儲的都是文本數據,那麼可使用字符流較爲方便:Writer.
由於操做的是一個文件。因此使用Writer中的FileWriter。
是否要提升效率呢?是,那麼就使用BufferedWriter.
BufferedWriter bufr = new BufferedWriter(new FileWriter("a.txt"));
附加需求:但願將這些文本數據按照指定的編碼表存入文件中。
既然是文本數據,並且仍是寫入到文件中,那麼使用的體系仍是Writer。
由於要指定編碼表,因此要使用Writer中的轉換流,OutputStreamWriter。
是否要提升效率,是,選擇BufferedWriter。
注意:雖然最終是文件,可是不能夠選擇FileWriter。由於該對象是使用默認編碼表。
輸出轉換流要接收一個字節輸出流進來,因此要使用OutputStream體系,而最終輸出到一個文件中,
那麼就要使用OutputStream體系中能夠操做的文件的字節流對象:FileOutputStream。
//String charSet = System.getProperty("file.encoding");
String charSet = "utf-8";
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),charSet);