Java程序中,對於數據的輸入/輸出
操做以「流(stream)」
的方式進行。數組
字節流(8bit)
,字符流(16 bit)
輸入流
,輸出流
節點流
,處理流
關於字節流和字符流的區別:單元測試
輸入流和輸出流測試
節點流和處理流 spa
節點流
:直接從數據源或者目的地讀寫數據3d
處理流
:不直接鏈接到數據源或目的地,而是「鏈接」在已存在的流(節點流或處理流)之上,經過對數據的處理爲程序提供更爲強大的讀寫功能。code
Java IO流體系 對象
Java中IO流體系以下表所示,最基本的四個抽象基類分別是:InputStream
、OutputStream
、Reader
、Writer
。表格每一列的類都是繼承與第一行的抽象基類的。blog
一般一個流的使用由如下4個步驟組成:繼承
好比以FileReader流爲例,那麼它的使用步驟是:圖片
雖然Java IO流體系有衆多的類,可是全部的流都基本按照這幾個步驟來使用的。下面記錄一下FileReader的使用,數據的讀入操做。
@Test public void testFileReader() throws IOException { // 拋出異常 // 1. 實例化File類對象,指明要操做的文件 File file = new File("Hello.txt"); // 2. 提供具體的流 FileReader fr = new FileReader(file); // 3. 數據的讀入 // read():返回讀入的一個字符,若是達到文件末尾,那麼返回-1 int data = fr.read(); while(data != -1){ System.out.print((char)data); data = fr.read(); } // 4. 流的關閉操做 fr.close(); }
上面例子中,經過File類實例化了一個File對象,而後將其當作參數傳入了FileReader類進行實例化,以後調用read()方法進行數據的讀入,最後執行流的關閉。
關於上面代碼有幾個須要注意的點:
File file = new File("Hello.txt");
這段代碼使用的是相對路徑,若是是使用IDEA進行編寫的,那麼這個相對路徑在單元測試方法和main方法中有所區別。在單元測試方法中使用相對路徑,那麼相對的是模塊的路徑,而在main方法中相對的是項目的路徑。好比,這裏模塊名Day07,這個模塊下有文件Hello.txt,而模塊位於項目JavaSenior下,那麼File類實例化後的實例文件路徑以下代碼所示:public class FileReaderTest { // 在main方法中,輸出:D:\code\Java\JavaSenior\Hello.txt public static void main(String[] args) { File file = new File("Hello.txt"); System.out.println(file.getAbsolutePath()); } // 在單元測試方法中,輸出:D:\code\Java\JavaSenior\Day07\Hello.txt @Test public void test4(){ File file = new File("Hello.txt"); System.out.println(file.getAbsolutePath()); } }
@Test public void test2(){ FileReader fr = null; try{ File file = new File("Hello.txt"); fr = new FileReader(file); int data; while ((data = fr.read()) != -1){ System.out.println((char)data); } }catch (IOException e){ e.printStackTrace(); }finally { try { if (fr != null){ fr.close(); } } catch (IOException e) { e.printStackTrace(); } } }
read()
方法:讀取單個字符。做爲整數讀取的字符,範圍在0-65535之間(2個字節的Unicode碼),若是已到達流的末尾,則返回-1。read(char cbuf[])
:將字符存入數組,而且返回本次讀取的字符數,若是到達流的末尾,則返回-1。@Test public void test3() { FileReader fr = null; try { // 1. File類的實例化 File file = new File("Hello.txt"); // 2. FileReader流的實例化 fr = new FileReader(file); // 3. 讀入的操做 char[] cbuf = new char[5]; int len; /* 假如Hello.txt裏的文件內容是helloworld123,這裏的read(cbuf)指的是讀取5個字符, 即第一次讀取hello,返回5,第二次讀取world,返回5, 第三次讀取123,由於只有123了,返回3,第四次返回-1。 因此3次循環,len變量的值爲5,5,3,最後一次爲-1。 */ while ((len = fr.read(cbuf)) != -1) { // 遍歷操做錯誤的寫法 // for (int i = 0; i < arr.length; i++) { // System.out.println(arr[i]); // } // 正確的遍歷操做一: // for (int i = 0; i < len; i++) { // System.out.print(arr[i]); // } // 錯誤的寫法二: // String str = new String(arr); // System.out.println(str); // 正確的寫法二: String str = new String(cbuf,0,len); System.out.print(str); } }catch (IOException e){ e.printStackTrace(); }finally { // 4. 流資源的關閉 try { if (fr != null) { fr.close(); } }catch (IOException e){ e.printStackTrace(); } } }
未完待續...