日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java】关于Java中的各种流

發布時間:2024/7/5 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java】关于Java中的各种流 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 IO流

1.1 概念

input:輸入(讀取)-----> 流:數據(字節/字符) -----> output:輸出(寫入)
輸入:把硬盤中的數據,讀取到內存中使用
輸出:把內存中的數據,寫入到硬盤中保存
內存:臨時存儲
硬盤:永久存儲
1個字符 = 2個字節
1個字節=8個二進制位

頂層父類

輸入流輸出流
字節流字節輸入流 InputStream字節輸出流 OutputStream
字符流字符輸入流 Reader字符輸出流 Writer

2 字節流

2.1 字節輸出流OutputStream

它是一個抽象類

共性成員方法:

  • public void close() :關閉此輸出流并釋放與此流相關聯的任何系統資源。當完成流的操作時,必須調用此方法,釋放系統資源。
  • public void flush() :刷新此輸出流并強制任何緩沖的輸出字節被寫出。
  • public void write(byte[] b) :將 b.length字節從指定的字節數組寫入此輸出流。
  • public void write(byte[] b, int off, int len) :從指定的字節數組寫入 len字節,從偏移量 off開始輸出到此輸出流。
  • public abstract void write(int b) :將指定的字節輸出流。1次寫1個字節。

  • 2.1.1 文件字節輸出流FileOutputStream

    ,extends OutputStream,把內存中的數據寫入硬盤的文件中。

    構造方法:創建一個 FileOutputStream 對象。根據參數傳遞的文件/文件路徑,創建一個空文件。把 FileOutputStream 對象指向創建好的文件。

  • FileOutputStream(String name):文件路徑
  • FileOutputStream(File file):文件

  • 寫入數據的原理(內存 —> 硬盤)

    Java程序 —> JVM —>OS —> OS調用寫數據的方法 —>把數據寫入文件中

    字節輸出流的使用步驟

  • 創建一個 FileOutputStream 對象,構造方法在傳遞寫入數據的目的地
  • 抵用 FileOutputStream 對象的write方法,把數據寫入文件中
  • 釋放資源,清空流占用的內存,提高程序效率

  • 把a寫入a.txt文件

    public abstract void write(int b)

    public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("a.txt");fos.write(97);fos.close();}

    原理:寫數據時會把十進制97轉為二進制1100001?,硬盤中存儲的數據都是字節,1個字節等于8個比特位。文本編輯器在打開文件時會查詢編碼表,把字節轉為字符表示,97—>a。


    一次寫入多個字節
    public void write(byte[] b)
    public void write(byte[] b, int off, int len) :把數組的一部分寫入文件

    public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream(new File("b.txt"));byte[] a = {65,66,67,68,69};//ABCDEbyte[] b = {-65,-66,-67,68,69};//烤紻E//如果寫的第一個字節是正數 顯示會查ascii碼表//如果是負數,第一個字節和第二個字節會組成一個中文顯示 查詢GBKfos.write(b);fos.write(a,1,2);//BCfos.close();}

    使用String類的方法把字符串轉換為字節數組。

    public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream(new File("b.txt"));byte[] b = "哈哈哈".getBytes();System.out.println(Arrays.toString(b));fos.write(b);fos.close();}

    GBK:兩個字節是一個中文
    UTF8:三個字節是一個中文


    數據的追加寫和換行寫
    追加寫的構造方法 append=true
    FileOutputStream(String name, boolean append)
    FileOutputStream(File file, boolean append)
    換行:win【\r\n】mac【/n】linux【/r】

    public static void main(String[] args) throws IOException {//追加寫FileOutputStream fos = new FileOutputStream(new File("b.txt"),true);for (int i = 0; i < 10; i++) {fos.write("哈哈哈".getBytes());//換行寫fos.write("\r\n".getBytes());}fos.close();}

    2.2 字節輸入流InputStream

    它是一個抽象類,是所有字節輸入流類的超類
    共性方法

    • int read()
    • int read(byte[] b)
    • void close

    2.2.1 文件字節輸入流FileInputStream

    作用:把硬盤中的數據,讀取到內存中使用

    構造方法

    • FileInputStream(String name)
    • FileInputStream(File file)

    構造方法的作用

  • 創建一個FileInputStream對象
  • 把FileInputStream對象指向指定構造方法中要讀取的文件

  • 讀取數據原理(硬盤—>內存)
    Java程序 —> JVM —>OS —>OS調用讀取數據的方法 —> 讀取文件

    字節輸出流的使用步驟

  • 創建FileInputStream對象,構造方法中綁定要讀取的數據源
  • 調用FileInputStream對象的read方法,讀取文件
  • 釋放資源
  • 注意:read每調用一次指針都會后移一位,如果while循環括號中不保存讀取的值,輸出的就是跳位讀取的值。

    一次讀取一個字節

    public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");int len = 0;while((len = fis.read())!=-1){//讀取一個字節并返回 文件末尾返回-1System.out.print((char) len);}fis.close();}

    一次讀取多個字節
    int read(byte[] b):
    注意:byte[]的作用是起緩沖作用,存儲每次讀取到的多個字節。數組長度一般定義為1024(1kb)或者1024的整數值。int返回值是每次讀取的有效字節個數。

    原理:創建一個byte數組,數組元素的初始值為0。開始讀取,把讀取出的數據存入byte數組,指針移動,b.length是一次讀取的字節個數。new String()可以把byte數組轉換為字符串輸出。read方法的返回值是有效讀取字節個數。


    public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");byte[] bytes = new byte[1024];int len = 0;while((len = fis.read(bytes))!=-1){System.out.print(new String(bytes,0,len));//打印byte中存的有效位}}

    2.3 字節流練習-文件復制

    原理
    創建一個輸入流的對象,再創建一個輸出流的對象,然后輸入流對象讀取文件內容,寫入輸出流指向的對象處。
    注意:應該先關閉輸出流(寫),再關閉輸入流(讀)。因為寫完了一定讀完了,但讀完了不一定寫完了。應該先開啟輸入流,再開啟輸出流,先讀后寫。

    public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("D:\\1.png");FileOutputStream fos = new FileOutputStream("E:\\1.png");byte[] bytes = new byte[1024];int len = 0;while((len=fis.read(bytes))!=-1){fos.write(bytes,0,len);}fos.close();fis.close();}

    2.4 字節流讀文件存在的問題

    在讀取中文字符的時候,可能不會顯示完整的字符,因為一個中文可能占用多個字節。按字節流讀取,每次只能讀取字符的一部分。所以文本文件一般用字符流進行讀寫
    GBK:1個中文2個字節
    UTF8:1個中文3個字節

    3 字符流

    3.1 字符輸入流Reader

    字符輸入流類最頂層的父類,是一個抽象類。

    共性方法

    • int read()
    • int read(char[] c)
    • void close()

    3.1.1 文件字符輸入流FileReader

    作用:把硬盤文件中的數據以字符的方式讀取到內存中

    構造方法:創建一個FileReader對象,把FileReader對象指向要讀取的文件/文件路徑

    • FileReader(String name)
    • FileReader(File file)

    使用步驟

  • 創建FileReader對象,構造方法中綁定要讀取的數據源
  • FileReader對象調用read方法
  • 關閉,釋放資源
  • 一次讀取一個字符

    public static void main(String[] args) throws IOException {FileReader fd = new FileReader("a.txt");int len = 0;while((len = fd.read())!=-1){System.out.print((char) len);}fd.close();}

    一次讀取多個字符

    字符數組 —> 字符串 new String(char[], int off, int len)構造方法

    public static void main(String[] args) throws IOException {FileReader fd = new FileReader("a.txt");char[] c = new char[1024];int len = 0;while((len = fd.read(c))!=-1){System.out.print(new String(c,0,len));}fd.close();}

    3.2 字符輸出流Writer

    共性方法

    • void write(int c) 寫入單個字符。
    • void write(char[] cbuf) 寫入字符數組。
    • abstract void write(char[] cbuf, int off, int len) 寫入字符數組的某一部分,off數組的開始索引,len寫的字符個數。
    • void write(String str) 寫入字符串。
    • void write(String str, int off, int len) 寫入字符串的某一部分,off字符串的開始索引,len寫的字符個數。
    • void flush() 刷新該流的緩沖。
    • void close() 關閉此流,但要先刷新它。

    3.2.1 文件字符輸出流FileWriter

    作用:內存中的字符數據寫入文件中

    構造方法

    • FileWriter(String name)
    • FileWriter(File file)

    作用:創建FileWriter對象,根據構造方法中傳遞的文件/文件路徑創建文件,會把FileWriter對象指向創建好的文件中。

    使用步驟

  • 創建FileWriter對象,構造方法中綁定寫入數據的目的地。
  • 使用FileWriter中的方法write,把數據寫入到內存緩沖區中。(字符轉換為字節的過程)
  • 使用FileWriter中的方法flush,把內存緩沖區的數據,刷新到文件中。
  • 釋放資源(會先把內存緩沖區的數據刷新到文件中)
  • 寫入單個字符

    public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("a.txt");//綁定寫入位置fw.write(97);//寫入緩沖區 字符-->字節fw.flush();//寫入文件fw.close();//釋放資源}

    flush和close方法的區別
    close在關閉之前會先把內存緩沖區的數據刷新到文件中,但close之后不能繼續使用write方法。flush同樣也是刷新操作,但flush之后可以繼續使用write方法。

    其他寫入方法

    • void write(char[] c):寫入字符數組
    • abstract void write(char[] c, int off, int len):寫入字符數組的某一部分
    • void write(String str):寫入字符串
    • void write(String str, int off, int len):寫入字符串的某一部分
    public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("a.txt");char[] c = {'a','b','c','d','e','f'};fw.write(c);fw.write('\n');fw.write(c,3,3);String str = "嘻嘻哈哈呵呵";fw.write(str);fw.write('\n');fw.write(str,1,3);fw.close();}

    續寫和換行寫
    同字節流輸出

    public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("c.txt",true);for (int i = 0; i < 10; i++) {fw.write("哈哈哈"+i);fw.write("\r\n");}fw.close();}

    4 IO流的異常處理

    在JDK1.7之前可以使用try-catch-finally處理流中的一次

    public static void main(String[] args) {FileWriter fw = null;try{fw = new FileWriter("F:\\c.txt",true);for (int i = 0; i < 10; i++) {fw.write("哈哈哈"+i);fw.write("\r\n");}}catch (IOException e){e.printStackTrace();}finally {if(fw != null){try {fw.close();} catch (IOException e) {e.printStackTrace();}}}}

    JDK7的新特性:可以在try后增加一個()( )(),括號中可以定義流對象,那么這個流對象的作用域就在try中有效,try執行完后,流對象自動釋放,不用寫finally【常用】

    public static void main(String[] args) {try(FileWriter fw = new FileWriter("F:\\c.txt",true)){for (int i = 0; i < 10; i++) {fw.write("哈哈哈"+i);fw.write("\r\n");}}catch (IOException e){e.printStackTrace();}System.out.println("哈哈哈哈哈");}

    JDK9的新特性,try前面可以定義對象,在try后邊的()中可以引入流對象的名稱。try執行完畢后,流對象可以釋放掉,不需要寫finally。【不常用】

    public static void main(String[] args) {FileReader fr = new FileReader("c.txt");FileWriter fw = new FileWriter("d.txt");try(fr;fw){char[] c = new char[1024];int len = 0;while((len = fr.read(c))!=-1){fw.write(c);}fw.flush();}catch (IOException e){e.printStackTrace();}System.out.println("哈哈哈哈哈");}

    5 屬性集

    java.util.Properties 繼承于Hashtable,來表示一個持久的屬性集。是唯一一個和IO流相結合的集合。

    它使用鍵值結構存儲數據,每個及其對應都是一個字符串。該類也被許多Java類使用,比如獲取系統屬性時, System.getProperties 方法就是返回一個Properties 對象。

    使用Properties存儲數據并遍歷取出

    操作字符串的特有方法

    • Object setProperty(String key, String value):相當于map.put(k, v)
    • String getProperty(String key):相當于map.get(k)
    • Set <String> stringPropertyNames():相當于map.keySet()
    public static void main(String[] args) {Properties prop = new Properties();prop.setProperty("張三","20");prop.setProperty("李四","25");prop.setProperty("王五","30");Set<String> set = prop.stringPropertyNames();for(String key: set){String value = prop.getProperty(key);System.out.println(key+" "+value);}}
    • 可以使用store方法把集合中的臨時數據,持久化寫入硬盤中存儲
    • void store(OutputStream out, String comments):字節輸出流,不能寫中文
    • void store(Writer writer, String comments):字符輸出流,可以寫中文

    comments是注釋,用來解釋保存的文件是做什么的,不可以使用中文,默認是Unicode編碼,一般使用空字符串

    使用步驟

  • 創建一個Proprorities對象,添加數據
  • 創建字節輸出流/字符輸出流對象,構造方法綁定輸出位置
  • 使用store方法把集合中的臨時數據持久化寫入硬盤中。
  • 釋放輸出流對象
  • public static void main(String[] args) throws IOException {Properties prop = new Properties();prop.setProperty("張三","20");prop.setProperty("李四","25");prop.setProperty("王五","30");FileWriter fw = new FileWriter("e.txt");prop.store(fw, "");fw.close();}
    • 可以使用load方法,把硬盤中保存的文件,讀取到集合中使用
    • void load(InputStream in):字節輸入流,不能讀取含有中文的鍵值對
    • void load(Reader r):字符輸入流,可以讀取含有中文的鍵值對

    使用步驟

  • 創建一個Properties對象,load堆區保存鍵值對的文件
  • 遍歷Properties集合
  • 注意

    • 鍵值對文件中,鍵和值默認的連接符可以使用=、空格
    • 可以使用#來注釋,被注釋的鍵值對不會再讀取
    • 鍵和值默認都是字符串,不用再加引號
    public static void main(String[] args) throws IOException {Properties prop = new Properties();prop.load(new FileReader("f.txt"));Set<String> set = prop.stringPropertyNames();for(String key: set){System.out.println(key+" "+prop.getProperty(key));}}

    6 緩沖流

    緩沖流,也叫高效流,是對4個基本的FileXxx 流的增強,所以也是4個流,按照數據類型分類:
    字節緩沖流: BufferedInputStream , BufferedOutputStream
    字符緩沖流: BufferedReader , BufferedWriter
    緩沖流的基本原理,是在創建流對象時,會創建一個內置的默認大小的緩沖區數組,通過緩沖區讀寫,減少系統IO次數,從而提高讀寫的效率。

    6.1 字節緩沖流

    6.1.1 字節緩沖輸出流BfferedOutputStream

    繼承自OutputStream,可使用父類共性方法(見2.1)

    構造方法

    • BufferedOutputStream(OutputStream out):創建一個新的緩沖輸出流,以數據寫入指定的底層輸出流。
    • BufferedOutputStream(OutputSteam out, int size):創建一個新的緩沖輸出流,以將具有指定緩沖區大小的數據寫入指定的底層輸出流。

    使用步驟

  • 創建FileOutputStream對象,構造方法中綁定輸出位置。
  • 創建BufferedOutputStream對象,構造方法中傳遞fos對象,提高fos對象效率。
  • 使用bos對象的write方法,把數據寫入到內部緩沖區中。
  • 使用bos對象的flush方法,把緩沖區的數據刷新到文件中。
  • 釋放資源,close會先調用flush刷新數據再關閉(所以第四步可省略)
  • public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("b.txt");BufferedOutputStream bos = new BufferedOutputStream(fos);bos.write("寫入內部緩沖區".getBytes());//字節輸出流 用字節bos.flush();bos.close();}

    6.1.2 字節緩沖輸入流BfferedInputStream

    繼承自InputStream,可使用父類共性方法(見2.2)

    構造方法

    • BufferedInputStream(InputStream in):創建一個新的緩沖輸入流,保存參數輸入流in。
    • BufferedInputStream(InputSteam in, int size):創建一個具有指定緩沖區大小的BufferedInputStream保存其參數,即輸入流。

    使用步驟

  • 創建FileInputStream對象,構造方法中綁定讀取位置。
  • 創建BufferedInputStream對象,構造方法中傳遞fis對象,提高fis對象的讀取效率。
  • 使用bis對象的read方法,把數據寫入到內部緩沖區中。
  • 釋放資源。
  • public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");BufferedInputStream bis = new BufferedInputStream(fis);/*int len = 0;while((len = bis.read()) != -1){System.out.print((char)len);}bis.close();*/byte[] bytes = new byte[1024];int len = 0;while((len = bis.read(bytes))!=-1){System.out.println(new String(bytes));}}

    6.1.3 基本和緩沖效率比較

    public static void main(String[] args) throws IOException {long s = System.currentTimeMillis();FileInputStream fis = new FileInputStream("D:\\1.png");FileOutputStream fos = new FileOutputStream("E:\\1.png");BufferedInputStream bis = new BufferedInputStream(fis);BufferedOutputStream bos = new BufferedOutputStream(fos);byte[] bytes = new byte[1024];int len = 0;while((len=bis.read(bytes))!=-1){bos.write(bytes,0,len);}bos.close();bis.close();long e = System.currentTimeMillis();System.out.println(e-s);}

    文件復制4MB的ppt的效率比較:

    基本流(一次讀一個字節):17757 ms
    緩沖流(一次讀一個字節):121 ms
    基本流 + 數組緩沖區(一次讀多個字節):27 ms
    緩沖流 + 數組緩沖區(一次讀多個字節):9 ms

    6.2 字符緩沖流

    6.2.1 字符緩沖輸出流BufferedWriter

    繼承自Writer,可使用父類共性方法(見3.2)

    構造方法

    • BufferedWriter(Writer out):創建一個使用默認大小輸出緩沖區的緩沖字符輸出流。
    • BufferedWriter(Writer out, int size):創建一個使用指定大小輸出緩沖區的緩沖字符輸出流。

    特有方法

    • void newLine():寫入一個行分隔符,它會根據不同的操作系統,獲取不同的行分隔符。

    使用步驟

  • 創建字符輸出流對象,構造方法中傳遞寫入地址
  • 創建字符緩沖區輸出流對象,構造方法中傳遞字符輸出流
  • 調用flush,將內存緩沖區中的數據刷新到文件中
  • 釋放資源
  • public static void main(String[] args) throws IOException {BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));for (int i = 0; i < 10; i++) {bw.write("哈哈哈哈");bw.newLine();bw.write("嘻嘻嘻嘻");bw.newLine();}bw.close();}

    6.2.2 字符緩沖輸入流BufferedReader

    繼承自Reader,可使用父類共性方法(見3.1)

    構造方法

    • BufferedReader(Reader in):創建一個使用默認大小輸入緩沖區的緩沖字符輸入流。
    • BufferedReader(Reader in, int size):創建一個使用指定大小輸入緩沖區的緩沖字符輸入流。

    特有方法

    • String readLine():讀取一行文本,讀取一行數據,流末尾返回null,readLine不讀換行符

    使用步驟

  • 創建字符輸入流對象,構造方法中傳遞讀取地址
  • 創建字符緩沖區輸入流對象,構造方法中傳遞字符輸入流
  • 調用read/readLine讀取
  • 釋放資源
  • public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("b.txt"));String line = null;while((line = br.readLine())!=null){System.out.println(line);}}

    6.3 緩沖流練習-文本排序

    b.txt內容:
    7.77777777777777
    3.張三3333333333
    5.王五5555555555
    1.大一1111111111
    4.李四4444444444
    2.小二2222222222
    6.六六6666666666

    public static void main(String[] args) throws IOException {Map<String , String> map = new HashMap<>();BufferedReader br = new BufferedReader(new FileReader("b.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("nb.txt"));String line;while((line = br.readLine())!=null){String[] split = line.split("\\.");map.put(split[0],split[1]);}//map會自動排序for(String key: map.keySet()){String value = map.get(key);bw.write(key+"."+value);bw.newLine();}bw.close();br.close();}

    7 轉換流

    7.1 字符編碼和字符集

    字符編碼
    計算機中儲存的信息都是用二進制數表示的,而我們在屏幕上看到的數字、英文、標點符號、漢字等字符是二進制數轉換之后的結果。按照某種規則,將字符存儲到計算機中,稱為編碼 。反之,將存儲在計算機中的二進制數按照某種規則解析顯示出來,稱為解碼 。比如說,按照A規則存儲,同樣按照A規則解析,那么就能顯示正確的文本f符號。反之,按照A規則存儲,再按照B規則解析,就會導致亂碼現象。

    字符編碼Character Encoding : 就是一套自然語言的字符與二進制數之間的對應規則。

    字符集
    字符集 Charset :也叫編碼表。是一個系統支持的所有字符的集合,包括各國家文字、標點符號、圖形符號、數字等。計算機要準確的存儲和識別各種字符集符號,需要進行字符編碼,一套字符集必然至少有一套字符編碼。常見字符集有ASCII字符集、GBK字符集、Unicode字符集等。

    ASCII是最基本的編碼表,GBK是中文編碼表
    Unicode是萬國碼,兼容各種語言,是應用中優先采用的編碼。

    7.2 編碼常見問題

    例如:在IDEA中,使用FileReader 讀取項目中的文本文件。由于IDEA的設置,都是默認的UTF-8編碼,所以沒有任何問題。但是,當讀取Windows系統中創建的文本文件時,由于Windows系統的默認是GBK編碼,就會出現亂碼。

    解決方法:使用轉換流

    7.3 轉換流相關內容

    字節轉換為字符(解碼)
    FileInputStream —> 查詢編碼表 —> FileReader

    7.3.1 OutputStreamWriter

    字符流通向字節流的橋梁
    可以指定編碼格式
    寫入你想寫入的編碼格式的文件中

    構造方法

    • OutputStreamWriter(OutputStream out):創建使用默認字符編碼的OutputStreamWriter(utf8)
    • OutputStreamWriter(OutputStream out, String charSet):創建使用指定字符編碼的OutputStreamWriter

    使用步驟

  • 創建OutputStreamWriter對象,構造方法中傳遞字節輸出流和指定編碼集
  • 使用osw對象中的write,把字符轉換為字節存在緩沖區中
  • 使用osw對象中的flush把字節刷新到文件中
  • 釋放資源
  • 你好 GBK 4字節 UTF8 6字節

    public static void main(String[] args) throws IOException {OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");osw.write("你好");osw.close();}

    7.3.2 InputStreamReader

    字節流通向字符流的橋梁
    可以指定編碼格式
    讀取字節解碼為字符 把看不懂的變成看得懂的

    構造方法

    • InputStreamReader(InputStream in):創建使用默認字符編碼的OutputStreamWriter(utf8)
    • InStreamReader(InputStream in, String charSet):創建使用指定字符編碼的InputStreamReader

    使用步驟

  • 創建InputStreamReader對象,構造方法中傳遞字節輸入流和指定編碼集
  • 使用isw對象中的read讀取文
  • 釋放資源
  • 注意:如果文件編碼和指定編碼不一致,則會發生亂碼

    public static void main(String[] args) throws IOException {InputStreamReader isr = new InputStreamReader(new FileInputStream("utf8.txt"),"utf-8");int len = 0;while((len = isr.read())!=-1){System.out.print((char)len);}isr.close();}

    7.4 練習:轉換文件編碼

    將GBK編碼的文本文件,轉換為UTF8編碼的文本文件

    public static void main(String[] args) throws IOException {InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk.txt"),"gbk");OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream("gbk2utf8.txt"),"utf-8");int len = 0;while((len = isr.read()) != -1){osr.write(len);}osr.close();isr.close();}

    8 序列化和反序列化

    8.1 概念

    ObjectOutputStream對象的序列化流
    把對象以流的方式寫入到文件中保存,叫寫對象,也叫對象的序列化。對象中包含的不僅是字符,使用字節流。

    ObjectInputStream對象的反序列化流
    把文件中的對象,以流的方式讀取出來,叫讀對象,也叫對象的反序列化。文件保存的都是字節,使用字節流。

    8.2 對象的序列化流ObjectOutputStream

    構造方法

    • ObjectOutputStream(OutputStream out)

    特有方法

    • void writeObject(Object obj)

    使用步驟

  • 創建ObjectOutputStream對象,構造方法中傳遞字節輸出流
  • 使用writeObject方法寫入對象
  • 釋放資源
  • 序列化和反序列化時,會拋出NotSerializableException沒有序列化異常。
    類通過實現Serializable接口以啟動序列化功能,沒有實現此接口的類無法使其任何狀態序列化或反序列化。
    Serializable接口也叫標記型接口,進行序列化和反序列化,必須要實現Serializable接口,給類添加標記。在使用時,會檢測是否有標記。

    使用前提
    Person類的實現 要加上implement Serializable

    public static void main(String[] args) throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));oos.writeObject(new Person("張三",15));oos.close();}

    8.3 對象的反序列化流ObjectInputStream

    構造方法

    • ObjectInputStream(InputStream in)

    特有方法

    • void readObject(Object obj) 讀取對象

    使用步驟

  • 創建ObjectOutputStream對象,構造方法中傳遞字節輸入流
  • 使用writeObject方法讀取對象
  • 釋放資源
  • 打印對象
  • readObject方法聲明拋出了ClassFoundException,class文件找不到異常,當不存在對象的class文件時拋出異常
    使用前提
    Person類的實現 要加上implement Serializable
    對象的class類文件要存在

    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Person.txt")); Object o = ois.readObject(); ois.close(); System.out.println(o);

    【注意!!!】
    InvalidClassException異常:序列化之后對類進行更改之后,不重新序列化,而是直接反序列化會出現異常。

    因為javac編譯器會把java文件編譯生成class文件。類如果實現了Serializable接口,就會根據類的定義給類的class文件添加一個序列化號serialVersionUID,輸出的文件也會寫入這個ID,反序列化的時候,會使用class文件的序列號和輸出文件的序列號比較,如果ID一致,則反序列化一致,否則會拋出InvalidClassException異常

    而修改了類的定義之后,會給class文件重新編譯生成一個新的序列號,但是輸出文件的序列號沒有改。

    解決方案:手動給類加一個序列號。無論是否修改類都不再修改序列號。

    自定義類中添加成員常量。

    private static final long serialVersionID = 1L;

    瞬態關鍵字transient
    static靜態關鍵字:靜態優先于非靜態加載到內存中,(靜態優先于對象),所以static修飾的成員變量是不能被序列化的,序列化的都是對象。
    【在上例中,如果Person類的age成員變量是靜態的,序列化和非序列化age將永遠是初始值0,無法更改】

    transient瞬態關鍵字:被它修飾的成員變量不能被序列化。如果想要對象中的成員變量不被序列化,可以使用瞬態關鍵字。

    8.4 練習:序列化集合

    當我們想在文件中保存多個對象的時候,可以把對象存在集合中,對集合進行序列化和反序列化。

    public static void main(String[] args) throws IOException, ClassNotFoundException {ArrayList<Person> list = new ArrayList<>();list.add(new Person("張三",15));list.add(new Person("李四",19));list.add(new Person("王五",20));ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("PersonList.txt"));oos.writeObject(list);ObjectInputStream ois = new ObjectInputStream(new FileInputStream("PersonList.txt"));Object o = ois.readObject();ArrayList<Person> list2 = (ArrayList<Person>) o;for (Person p : list2){System.out.println(p);}ois.close();oos.close();}

    9 打印流

    9.1 PrintSteam類

    平時我們在控制臺打印輸出,是調用print方法和println方法完成的,這兩個方法都來自于java.io.PrintStream類,該類能夠方便地打印各種數據類型的值,是一種便捷的輸出方式。

    特點

    • 不會拋出IO異常
    • 只負責輸出,不負責讀取
    • 特有方法print、println

    構造方法

    • PrintStream(File file):輸出目的地是一個文件
    • PrintStream(OutputStream out):輸出目的地是一個字節輸出流
    • PrintStream(String path):輸出目的地是一個文件路徑

    注意

    • 如果用繼承父類的write方法寫數據,查看數據的時候就會查詢編碼表,再打印
    • 如果使用特有方法print和println則會原樣輸出
    public static void main(String[] args) throws IOException, ClassNotFoundException {PrintStream ps = new PrintStream("a.txt");ps.write(97);ps.write('\n');ps.println(97);ps.print("a1#$@哈哈哈");ps.close();}

    可以改變輸出語句的目的地,即打印流的流向。
    輸出語句,默認在控制臺輸出,使用System.setOut方向改變輸出語句的目的地改為參數中傳遞的打印流的目的地。

    public static void main(String[] args) throws IOException, ClassNotFoundException {System.out.println("控制臺輸出:哈哈哈");PrintStream ps = new PrintStream("打印流輸出");System.setOut(ps);System.out.println("打印流輸出:哈哈哈");//控制臺不輸出這一句 而是寫在"打印流輸出"文件中}

    總結

    以上是生活随笔為你收集整理的【Java】关于Java中的各种流的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产一级做a爰片在线看免费 | 制服诱惑一区 | 91中文字幕永久在线 | 亚洲激情网 | 99999视频 | 一级欧美黄色片 | 日本在线天堂 | 免费大黄网站 | 不卡中文| 免费观看黄色网址 | 高清一区二区 | 8x8ⅹ国产精品一区二区二区 | 精品日本一区二区三区在线观看 | 男人的天堂成人 | 无套中出丰满人妻无码 | 高清不卡av | 草逼国产 | 成人观看视频 | 亚洲天堂资源 | 青草一区二区 | 国内性爱视频 | 国产一区亚洲一区 | 久久sp| 久久精品—区二区三区舞蹈 | 黄色片欧美 | 久久午夜激情 | 精品动漫一区二区 | 国产乱free国语对白 | 翔田千里88av中文字幕 | 丁香花电影免费播放在线观看 | fc2ppv色の美マンに中出し | www.av72 | 一区二区三区久久精品 | 一区小视频 | 香蕉二区| 亚洲欧美日韩在线一区二区 | 欧美一区二区三区四区在线观看 | 国内自拍视频在线播放 | 91免费视频入口 | 日韩福利视频一区 | 欧美一级片免费看 | 一区二区不卡视频 | 欧美日韩国产一区二区 | 这里只有精品国产 | 九九精品在线观看视频 | 日本免费一区二区三区四区五六区 | 制服丝袜一区在线 | 悠悠色综合 | 日日摸夜夜添夜夜添高潮喷水 | 污污网站免费 | 毛片大全 | 亚洲精品91天天久久人人 | 婷婷久久久久久 | 伊人春色在线观看 | 免费看成人av | 九九视频免费在线观看 | 国产外围在线 | 亚洲第一色网站 | 女人被狂躁c到高潮喷水电影 | 欧美少妇一区二区三区 | 丝袜美腿亚洲一区二区图片 | 日本少妇bbb| 成人手机av| 爱情岛亚洲首页论坛小巨 | 国产艳情片 | 欧美午夜精品一区 | 1级性生活片 | 三年中国片在线高清观看 | 日韩黄色成人 | 无码人妻久久一区二区三区蜜桃 | 亚洲欧美第一页 | 亚洲在线成人 | 欧美精品久久久久久久免费 | 久久不雅视频 | 久久aⅴ国产欧美74aaa | 大陆熟妇丰满多毛xxxⅹ | 成人做爰66片免费看网站 | 精品久久久99 | 日本一区二区三区电影在线观看 | 日韩在线视频在线 | 这里只有精品免费视频 | 亚洲AV无码久久精品国产一区 | 丝袜诱惑一区二区 | 乳色吐息免费看 | 免费在线一区二区 | 一级二级在线观看 | 久久99精品久久久久久 | 亚洲福利视频一区二区 | 成人羞羞国产免费动态 | 亚洲色图在线播放 | 中文字幕无码人妻少妇免费 | 天天热天天干 | 97视频成人 | 国产福利视频 | 亚洲精选一区二区 | 亚洲va韩国va欧美va精品 | 91午夜精品 | 欧美一级视频免费观看 | 人妖天堂狠狠ts人妖天堂狠狠 |