我們知道數據會在內存和硬盤之間交互,先來看一個圖:
對於數據的輸入和輸出,是參照內存而言的。內存中的數據寫入硬盤,即相對於內存是輸出(Output),為寫(write),而硬盤寫入內存,則為輸入(Input),為讀(read)。因為在數據在管道中傳輸,相當於發生了數據的流動,即有了對應的輸出流(OutputStream)和輸入流(InputStream)。
1.什么是IO?
I/O是Input/Output的縮寫。通過IO操作可以完成對硬盤文件的讀和寫。
2.IO的分類
-
根據數據流的流動方向:
- 內存中流向硬盤中,稱為:輸出流;
- 硬盤中流向內存,稱為:輸入流。
-
根據讀取數據的方式:
-
字節流:一次讀取一個字節,即八個二進制位。字節流是萬能流,可以用於讀取文本文件、圖片、音頻、視頻等。
-
字符流:每次讀取一個字符。字符流只能讀取普通的文本文件,其就是為了方便讀取文本文件的。
(注意:word是有格式的,不屬於普通文本文件,可以簡單理解為普通文本文件可以用記事本打開,但不一定是txt結尾。)
例:
一個txt文本中的內容為:a中b國c人
采用字符流的方式讀取:第一次讀a,第二次讀中,第三次讀b......
采用字節流的方式讀取:第一次讀a,第二次讀中的一半,第三次讀中的另外一半,第四次讀b......
這里需要注意的是:
讀取的字節和字符是相對於Windows系統而言的,在Windows系統中,一個英文字符是一個字節,一個中文是兩個字節,所以讀取漢字時,每次只能讀一半。(區別於Java中char為兩個字節,不要混淆了!)
-
3.IO的四大家族
Java中的IO流都已經寫好了,不需要我們去寫。簡而言之,我們需要做的就是了解IO中有哪些流操作的類,它們的特點是什么,並且要學會如何去使用它們,是字節流還是字符流,怎么new對象,怎么讀,怎么寫,其它常用方法是什么。(面向api文檔學習)
Java中的流的類都在java.io下,即java.io.*;
Java中的流主要分為四大家族:字節輸入流(InputStream)、字節輸出流(OutputStream)、字符輸入流(Writer)、字符輸出流(Reader)。
以Stream結尾的為字節流,以Reader或者Writer結尾的為字符流。
並且四大家族有一些共同的特點:
-
都為抽象類;
-
都實現了closeable接口,所以都擁有close(),用於操作之后關閉流,釋放資源;
(流畢竟是一個管道,用於內存和硬盤之間的通道,如果不關閉的話,會消耗很多的資源,所以用后一定要關閉)
-
其中輸出流OutputStream、Writer還實現了flushable接口,所以擁有flush(),flush()的作用是將管道中剩余未輸出的數據強行清空,在寫入數據時,最后使用flush()將管道中可能剩余的數據全部寫到硬盤文件中,如果沒有flush(),就有可能丟失一部分數據。
(所有的輸出流都擁有flush(),並且一定要進行此操作,防止數據的丟失)
4.需要學習掌握的16個流
因為Java四大家族的首領都是抽象類,所以它們擁有很多的子類,我們學習也是學習它們的子類,主要學習以下16個:
-
文件操作流:FileInputStream、FileOutPutStream、FileWriter、FileReader;
-
轉換流:InputStreamReader、InputStreamWriter;
(注意,轉換流雖然有Stream也有Reader/Writer,但是是看什么結尾的,所以轉換流是字符流,就是將字節流轉換為字符流的。)
-
緩沖流:BufferedInputStream、BufferedOutPutStream、BufferedWriter、BufferedReader;
-
數據流:DataInputStream、DataOutputStream;
-
對象流:ObjectInputStream、ObjectOutputStream;
-
標准輸出流:PrintStream、PrinterWriter。
雖然看着很多(實際好像也真的很多),但是只要學習了其中的一對輸入輸出,只要了解其特性,其它基本都是照葫蘆畫瓢了。