字節數組流ByteArrayInputStream和ByteArrayOutputStreamjava
常常用在須要流和數組之間轉化數組
FileInputStream是把文件當作數據源。ByteArrayInputStream則是把內存中的」某個字節數組對象」當作數據源。app
import java.io.ByteArrayInputStream; import java.io.IOException; public class TestByteArray { public static void main(String[] args) { //將字符串轉變成字節數組 byte[] b = "abcdefg".getBytes(); test(b); } public static void test(byte[] b) { ByteArrayInputStream bais = null; StringBuilder sb = new StringBuilder(); int temp = 0; //用於保存讀取的字節數 int num = 0; try { //該構造方法的參數是一個字節數組,這個字節數組就是數據源 bais = new ByteArrayInputStream(b); while ((temp = bais.read()) != -1) { sb.append((char) temp); num++; } System.out.println(sb); System.out.println("讀取的字節數:" + num); } finally { try { if (bais != null) { bais.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
數據流DataInputStream和DataOutputStreamdom
數據流將「基本數據類型與字符串類型」做爲數據源,從而容許程序以與機器無關的方式從底層輸入輸出流中操做Java基本數據類型與字符串類型。ide
public class TestDataStream { public static void main(String[] args) { DataOutputStream dos = null; DataInputStream dis = null; FileOutputStream fos = null; FileInputStream fis = null; try { fos = new FileOutputStream("D:/data.txt"); fis = new FileInputStream("D:/data.txt"); //使用數據流對緩衝流進行包裝,新增緩衝功能 dos = new DataOutputStream(new BufferedOutputStream(fos)); dis = new DataInputStream(new BufferedInputStream(fis)); //將以下數據寫入到文件中 dos.writeChar('a'); dos.writeInt(10); dos.writeDouble(Math.random()); dos.writeBoolean(true); dos.writeUTF("北京尚學堂"); //手動刷新緩衝區:將流中數據寫入到文件中 dos.flush(); //直接讀取數據:讀取的順序要與寫入的順序一致,不然不能正確讀取數據。 System.out.println("char: " + dis.readChar()); System.out.println("int: " + dis.readInt()); System.out.println("double: " + dis.readDouble()); System.out.println("boolean: " + dis.readBoolean()); System.out.println("String: " + dis.readUTF()); } catch (IOException e) { e.printStackTrace(); } finally { try { if(dos!=null){ dos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(dis!=null){ dis.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(fos!=null){ fos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(fis!=null){ fis.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
對象流學習
若是要對某個對象進行讀寫操做,咱們須要學習一對新的處理流:ObjectInputStream/ObjectOutputStream。ui
ObjectInputStream/ObjectOutputStream是以「對象」爲數據源,可是必須將傳輸的對象進行序列化與反序列化操做。spa
注:序列化實體類實現序列化接口時orm
serialVersionUID適用於Java的序列化機制。簡單來講,Java的序列化機制是經過判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVersionUID進行比較,若是相同就認爲是一致的,能夠進行反序列化,不然就會出現序列化版本不一致的異常,便是InvalidCastException。public class TestObjectStream { public static void main(String[] args) throws IOException, ClassNotFoundException { write(); read(); } /**使用對象輸出流將數據寫入文件*/ public static void write(){ // 建立Object輸出流,幷包裝緩衝流,增長緩衝功能 OutputStream os = null; BufferedOutputStream bos = null; ObjectOutputStream oos = null; try { os = new FileOutputStream(new File("d:/bjsxt.txt")); bos = new BufferedOutputStream(os); oos = new ObjectOutputStream(bos); // 使用Object輸出流 //對象流也能夠對基本數據類型進行讀寫操做 oos.writeInt(12); oos.writeDouble(3.14); oos.writeChar('A'); oos.writeBoolean(true); //對象流可以對對象數據類型進行讀寫操做 //Date是系統提供的類,已經實現了序列化接口 //若是是自定義類,則須要本身實現序列化接口 oos.writeObject(new Date()); } catch (IOException e) { e.printStackTrace(); } finally { //關閉輸出流 if(oos != null){ try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } if(bos != null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if(os != null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } /**使用對象輸入流將數據讀入程序*/ public static void read() { // 建立Object輸入流 InputStream is = null; BufferedInputStream bis = null; ObjectInputStream ois = null; try { is = new FileInputStream(new File("d:/bjsxt.txt")); bis = new BufferedInputStream(is); ois = new ObjectInputStream(bis); // 使用Object輸入流按照寫入順序讀取 System.out.println(ois.readInt()); System.out.println(ois.readDouble()); System.out.println(ois.readChar()); System.out.println(ois.readBoolean()); System.out.println(ois.readObject().toString()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉Object輸入流 if(ois != null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } if(bis != null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
轉換流對象
InputStreamReader/OutputStreamWriter用來實現將字節流轉化成字符流。
System.in是字節流對象,表明鍵盤的輸入,若是咱們想按行接收用戶的輸入時,就必須用到緩衝字符流BufferedReader特有的方法readLine(),可是通過觀察會發如今建立BufferedReader的構造方法的參數必須是一個Reader對象,這時候咱們的轉換流。
而System.out也是字節流對象,表明輸出到顯示器,按行讀取用戶的輸入後,而且要將讀取的一行字符串直接顯示到控制檯,就須要用到字符流的write(String str)方法,因此咱們要使用OutputStreamWriter將字節流轉化爲字符流。
使用InputStreamReader接收用戶的輸入,並輸出到控制檯
public class TestConvertStream { public static void main(String[] args) { // 建立字符輸入和輸出流:使用轉換流將字節流轉換成字符流 BufferedReader br = null; BufferedWriter bw = null; try { br = new BufferedReader(new InputStreamReader(System.in)); bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 使用字符輸入和輸出流 String str = br.readLine(); // 一直讀取,直到用戶輸入了exit爲止 while (!"exit".equals(str)) { // 寫到控制檯 bw.write(str); bw.newLine();// 寫一行後換行 bw.flush();// 手動刷新 // 再讀一行 str = br.readLine(); } } catch (IOException e) { e.printStackTrace(); } finally { // 關閉字符輸入和輸出流 if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }