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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

三万字的java I/O流基础总结看完肯定能把女朋友教会

發布時間:2024/10/14 编程问答 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 三万字的java I/O流基础总结看完肯定能把女朋友教会 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.



目錄:
1.File類詳解
2.I/O流概述
3.字節輸出流(OutputStream)
4.字節輸入流(InputStream)
5. 字符流概述
6.字符輸入流(Reader)
7.字符輸出流(Writer)
8.Properties類詳解
9.緩沖流概述
10.字節緩沖流(BufferedInputStream,BufferedOutputStream)
11.字符緩沖流(BufferedReader,BufferedWriter)
12.緩沖流高效率測試
13.轉換流概述
14. InputStreamReader類和 OutputStreamWriter類
15. 序列化
16.打印流

1.File類詳解

(1)首先File的位置:java.io.File

(2)File的作用

1.File類是專門對文件進行操作的類,只能對文件本身進行操作,不能對文件內容進行操作
2.File類是文件和目錄路徑名的抽象表示,主要用于文件和目錄的創建、查找和刪除等操作

(3)File類的構造方法

  • public File(String pathname):通過將給定的路徑名字符串轉換為抽象路徑名來創建新的 File實例。(說白了就是你給一個正確的字符串里邊包含路徑和文件名,然后按照這個路徑和你給的文件名創建相應的File對象)
  • public File(String parent, String child):從父路徑名字符串和子路徑名字符串創建新的 File實例。
  • public File(File parent, String child):從父抽象路徑名和子路徑名字符串創建新的 File實例。
  • 說著當然難受,上代碼:

    package untl1; import java.io.File; public class MyFile {public static void main(String[] args) {String str1="d:\\1\\a.txt";File file1=new File(str1);//運行結果創建一個為d:\\1\\a.txt的File對象String str2="d:";String str3="1\\a.txt";File file2=new File(str2,str3);//運行結果創建一個為d:\\1\\a.txt的File對象String str4="d:";String str5="1\\a.txt";File file3=new File(str4);File file4=new File(file3,str5);//運行結果創建一個為d:\\1\\a.txt的File對象} }

    這里有幾個注意點:

    1.一個File對象代表硬盤中實際存在的一個文件或者目錄
    2.File類構造方法不會給你檢驗這個文件或文件夾是否真實存在,因此無論該路徑下是否存在文件或者目錄,都不影響File對象的創建。
    3.創建的是File流對象,并不是已經在你的電腦磁盤上創建了相應的文件或者目錄
    4.你給的路徑一定要已經存在,如果你想創建一個d:\a\b\c.txt的File流對象,那么a和b目錄一定要已經存在,否則程序會拋出異常,因為系統找不到指定路徑
    5.如果你不指定路徑,那么系統會默認把你想建的文件或者目錄創建在本項目的路徑下

    (4)關于相對路徑和絕對路徑:

    package untl1; import java.io.File; public class MyFile {public static void main(String[] args) {String str1="d:\\1\\a.txt";File file1=new File(str1);System.out.println(file1.getAbsolutePath());//運行結果:d:\1\a.txtFile file2=new File("b.txt");//這就是項目下的相對路徑System.out.println(file2.getAbsolutePath());//運行結果:C:\Users\86166\IdeaProjects\until\b.txt} }

    這里有幾點注意事項

    1.路徑不區分大小寫
    2.路徑分隔符可以是兩個反斜杠\\還可以是一個正斜杠/
    3.相對路徑是一個簡化的路徑,絕對路徑是以盤符開頭的路徑

    (4)File類的常用方法

    方法名作用
    public String getAbsolutePath()返回此File的絕對路徑名字符串。
    public String getPath()將此File轉換為路徑名字符串。
    public String getName()返回由此File表示的文件或目錄的名稱。
    public long length()返回由此File表示的文件的長度。
    public boolean exists()此File表示的文件或目錄是否實際存在。
    public boolean isDirectory()此File表示的是否為目錄。
    public boolean isFile()此File表示的是否為文件。
    public boolean createNewFile()文件不存在,創建一個新的空文件并返回true,文件存在,不創建文件并返回false。
    public boolean delete()刪除由此File表示的文件或目錄。
    public boolean mkdir()創建由此File表示的目錄。
    public boolean mkdirs()創建由此File表示的目錄,包括任何必需但不存在的父目錄。

    關于常用方法的注意事項

    1.我們創建File對象沒有在磁盤上創建相應的文件和目錄,在磁盤上創建用createNewFile()以及mkdir()與mkdirs()
    2.如果此File表示目錄,則目錄必須為空才能用delete刪除。
    3.mkdirs()和mkdir()方法類似,但mkdir(),只能創建一級目錄,mkdirs()可以創建多級目錄比如//a//b//c

    (5)關于目錄的遍歷
    先介紹兩種方法:

    public String[] list():返回一個String數組,表示該File目錄中的所有子文件或目錄。
    public File[] listFiles():返回一個File數組,表示該File目錄中的所有的子文件或目錄。

    下面用File[] listFiles()舉個例子:

    package untl1; import java.io.File; import java.io.IOException; public class MyFile{public static void main(String[] args)throws IOException{File fp=new File("d:\\1");printF(fp);}static void printF(File fp){System.out.println(fp.getName());if(fp.isDirectory())//如果判斷它是一個目錄{File arr[]=fp.listFiles();//返回所有的子目錄和子文件for(File o:arr)//用for循環進行遍歷{printF(o);}}} } //運行結果是把所有d:\\1目錄下的所有文件和目錄名打印出來

    再使用File[] listFiles()的注意事項:

    1.指定的目錄必須存在
    2.指定的必須是目錄。否則容易引發返回數組為null,出現NullPointerException異常

    2.I/O流概述

    (1)I/O表述:
    Java的IO流是實現輸入/輸出的基礎,它可以方便地實現數據的輸入/輸出操作,在Java中把不同的輸入/輸出源(鍵盤、文件、網絡連接等)抽象表述為“流”(stream),通過流的方式允許Java程序使用相同的方式來訪問不同的輸入輸出源。 stream是從起源(source)到接收(sink)的有序數據。Java把所有傳統的流類型(類或抽象類)都放在java.io包中,用以實現輸入輸出功能。

    (2)I/O分類:
    根據數據的流向分為:

    1.輸入流 :把數據從其他設備上讀取到內存中的流。
    2.輸出流 :把數據從內存 中寫出到其他設備上的流。

    根據數據的類型分為:

    1.輸入流 :以字節為單位,讀寫數據的流。
    2.輸出流 :以字符為單位,讀寫數據的流。
    字節流和字符流的操作方式幾乎完全一樣,區別只是操作的數據單元不同而已。字節
    流操作的數據單元是字節,字符流操作的數據單元是字符,Java中一個字符兩個字節,字節流適合讀取視頻,圖片音頻等,字符流適合讀取純文本文件我們還要必須明確一點的是,一切文件數據(文本、圖片、視頻等)在存儲時,都是以二進制數字的形式保存,都一個一個的字節,那么傳輸時一樣如此。所以,字節流可以傳輸任意文件數據。在操作流的時候,我們要時刻明確,無論使用什么樣的流對象,底層傳輸的始終為二進制數據。

    輸入輸出流都是相對于內存而言,從內存中出來就是輸出,到內存中是輸入

    (3)四種流類型的祖先(都是繼承Object類):

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

    (4)I/O流概念模型:


    3.字節輸出流(OutputStream)

    1.關于OutputStream
    所在位置:java.io.OutputStream
    簡介:字節輸出流的所有類的超類

    2.關于字節輸出流的常用方法:

    方法名作用
    public void close()關閉此輸出流并釋放與此流相關聯的任何系統資源。
    public void flush()刷新此輸出流并強制任何緩沖的輸出字節被寫出。
    public void write(byte[] b)將 b.length個字節從指定的字節數組寫入此輸出流。
    public void write(byte[] b, int off, int len)從指定的字節數組寫入 len字節,從偏移量 off開始輸出到此輸出流。 也就是說從off個字節數開始讀取一直到len個字節結束
    public abstract void write(int b)將指定的字節輸出流。

    以上五個方法則是字節輸出流都具有的方法,由父類OutputStream定義提供,子類都會共享以上方法

    3.FileOutputStream類
    (1)FileOutputStream概述:
    由于OutputStream是一個抽象類無法實例化對象,那么就需要OutputStream的子類,FileOutputStream是其的一個子類,文件輸出流,用于把數據從內存寫入到文件中

    (2)FileOutputStream的構造方法:

  • public FileOutputStream(File file):根據File對象為參數創建對象。
  • public FileOutputStream(String name): 根據名稱字符串為參數創建對象。
  • 構造方法的作用:

    • 1.創建一個FileOutputStream的對象
    • 2.會根據構造方法傳遞的文件/文件路徑,創建一個空的文件
    • 3.會把FileOutputStream的對象指向創建好的文件

    (3)那么把數據寫進文件的原理:
    我們編寫好的Java程序運行后,Java虛擬機會找操作系統,調用Windows寫數據的方法,然后把數據寫到文件中(由內存--------》寫入磁盤)
    java程序——》Jvm(虛擬機)——》OS(操作系統)——》OS調用寫數據方法——》把數據寫入文件中

    (4)FileOutputStream的使用步驟:

    1.創建一個FileOutputStream的對象,構造方法傳遞寫入數據的目的地
    2.調用FileOutputStream實例化對象write方法,把數據寫入文件中
    3.釋放資源(流在使用的時候會占用一定的內存資源,使用后關閉會提高程序的效率)

    write也分為三種寫入方式:

    1.public void write(int b):一個字節一個字節的寫進文件
    2.public void write(byte[] b):以一個字節數組的方式寫進文件
    3.public void write(byte[] b,int off,int len):寫進以off索引開始len個字節

    實例:

    package untl1; import java.io.FileOutputStream; import java.io.IOException; public class MyFile{public static void main(String[] args) throws IOException {FileOutputStream file1=new FileOutputStream("d:1\\a.txt");file1.write(97);file1.close();byte arr[]={98,99,100};FileOutputStream file2=new FileOutputStream("d:1\\a.txt");file2.write(arr);file2.close();byte brr[]={101,102,103};FileOutputStream file3=new FileOutputStream("d:1\\a.txt");file3.write(brr,1,2);file3.close();} }

    整個程序運行下來a.txt最終只會寫進:fg
    why?
    首先看第一次寫進,注意寫數據的時候會把十進制的97轉換成二進制,因為任意的文本編輯器(記事本等等)在打開的時候,都會查詢編碼表,把字節轉換成字符表示

    0~127:查詢ASCII表
    其他值:查詢系統默認碼表(中文GBK)這里有個地方需要注意,當我們第一個字節是負數,那么會和后邊的一個字符組成中文顯示比如{-1234,2234,-342,4233,534}就會前兩個組成文字顯示,第三個和第四個會組成漢字顯示,由于第五個不是負數就會按照相應字符顯示

    所以第一次就只寫進去一個字符a

    那么該第二次寫了,這里注意:在創建輸出流對象的時候,如果你有這個文件,那么會清空文件里邊的數據,如果沒有就新建一個空白文件,所以第二次再寫完后a.txt里邊只有bcd三個字符

    同理進行第三次寫文件,最終只寫進了fg

    接下來認識一個String的方法:

    getBytes():把字符串轉換成字節數組

    這樣方便我們把字符串寫進文件
    例子:

    package untl1; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; public class MyFile{public static void main(String[] args) throws IOException {FileOutputStream file1 = new FileOutputStream("d:1\\c.txt");String str="我想睡覺";byte arr[]=str.getBytes();System.out.println(Arrays.toString(arr));//打印轉換成字符串所對應的字節數組file1.write(arr);file1.close();} } 運行結果:把我想睡覺寫進了文件

    (5)FileOutputStream實現數據追加續寫、換行
    上邊講了,每次創建流對象都會清空文件的數據,那么如何保留目標文件中數據,還能繼續追加新數據呢?使用下邊兩個構造方法:

    1、public FileOutputStream(File file, boolean append)
    2、public FileOutputStream(String name, boolean append)

    這兩個構造方法,第二個參數中都需要傳入一個boolean類型的值,true 表示追加數據,false 表示不追加也就是清空原有數據。這樣創建的輸出流對象,就可以指定是否追加續寫了

    在Windows系統中換行是\r\n
    我們只需要把換行所代表的字符串寫進文件,即可實現換行功能
    例如:

    package untl1; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; public class MyFile{public static void main(String[] args) throws IOException {FileOutputStream file1 = new FileOutputStream("d:1\\c.txt");byte arr[]={97,98,99,100};System.out.println(Arrays.toString(arr));for (byte a:arr){file1.write(a);file1.write("\r\n".getBytes());}file1.close();} } 運行結果: 文件里邊寫進了: a b c d

    4.字節輸入流(InputStream)

    1.關于InputStream
    所在位置:java.io.InputStream
    簡介:字節輸入流的所有類的超類

    2.字節輸入流的常用方法:

    方法作用
    public void close()關閉此輸入流并釋放與此流相關聯的任何系統資源。
    public abstract int read()從輸入流讀取數據的下一個字節。
    public int read(byte[] b)該方法返回的int值代表的是讀取了多少個字節,讀到幾個返回幾個,讀取不到返回-1

    以上三個方法則是字節輸入流都具有的方法,由父類InputStream定義提供,子類都會共享以上方法

    3.FileInputStream類
    (1)FileOutputStream概述:
    由于InputStream是一個抽象類無法實例化對象,那么就需要InputStream的子類,FileOutputStream是其的一個子類,文件輸入流,用于從文件種讀取字節

    (2)FileInputStream的構造方法

    1、FileInputStream(File file): 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的 File對象 file命名。
    2、FileInputStream(String name): 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的路徑名name命名。

    構造方法的作用:

    • 1.創建一個FileInputStream流對象
    • 2.會把FileInputStream對象指定構造方法內的文件

    (3)讀取數據的原理:
    我們編寫好的Java程序運行后,Java虛擬機會找操作系統,調用Windows讀取數據的方法,然后把數據寫到文件中(由磁盤--------》讀入內存)
    java程序——》Jvm(虛擬機)——》OS(操作系統)——》OS調用寫數據方法——》把數據寫入文件中

    (4)FileInputStream的使用步驟:

    1.創建FileInputStream對象,構造方法中綁定要讀取的數據
    2.使用FileInputStream對象中的read方法,讀取文件
    3.釋放資源

    read的兩種讀取方式

  • public int read():每次可以讀取一個字節的數據,提升為int類型,讀取到文件末尾,返回-1
  • public int read(byte b[]):每次讀取b的長度個字節到數組中,,返回讀取到的有效字節個數,讀取到末尾時,返回-1
    這里注意兩種返回值不一樣,第一種方法的返回值是讀取的字節對應的int類型的值,而第二種方法的返回值是所讀取的字節數
    每次讀完文件指針會自動往后移動
  • 實例:

    這里先介紹String的兩種構造方法:

    1.public String(byte bytes[]):給定一個字節數組會把字節數組轉換成字符串
    2.public String(byte bytes[], int offset, int length):從下標offest開始讀取length個字節并轉換成字符串
    這里的構造方法都有自動解碼的功能,默認編碼utf-8

    package untl1; import java.io.FileInputStream; import java.io.IOException; public class MyFile{public static void main(String[] args) throws IOException {FileInputStream file1=new FileInputStream("d:/1/c.txt");int len=0;while( (len=file1.read())!=-1){System.out.println((char)len);}FileInputStream file2=new FileInputStream("d:/1/c.txt");len=0;byte arr[]=new byte[2];while((len=file2.read(arr))!=-1){System.out.println(new String(arr));}} }

    d:/1/c.txt文件內容:

    運行結果:

    (5)復制圖片原理:

    例子:

    package untl1; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class MyFile {public static void main(String[] args) throws IOException {FileInputStream file1= new FileInputStream("d:\\0.jpg");FileOutputStream file2= new FileOutputStream("d:1\\00.jpg");byte arr[] = new byte[1024];int len=0;while((len=file1.read(arr))!=-1){file2.write(arr);}file1.close();file2.close();} } 運行結果: d盤下的0.jpg這張圖片會被復制到d盤1目錄下,且復制后在1目錄下的圖片名字為00.jpg

    1.由于只創建一次輸出流對象所以在寫進文件的時候,寫文件的指針自動后移,所以不必用追加寫的方式創建FileOutputStream對象
    2.FileInputStream和FileOutputStream由于都是對文件操作,所以指定的路徑不能是目錄

    5.字符流概述

    (1)我們在使用字節流的時候,可能會出現一些小問題,就是在遇到中文字符的時候,有時候讀取的時候會顯示亂碼的問題,那是因為我們字節是一個一個讀取,然而一個中文字符會占用幾個字節,假如你一個漢字占用三個字節,你只讀取了其中的兩個字節,那么是不會顯示漢字的,所以亂碼就理所應當了。

    盡管字節流也能有辦法決絕亂碼問題,但是還是比較麻煩,于是java就有了字符流,字符為單位讀寫數據,字符流專門用于處理文本文件。如果處理純文本的數據優先考慮字符流,其他情況就只能用字節流了(圖片、視頻、等等只文本例外)。
    從另一角度來說:字符流 = 字節流 + 編碼表

    字符流的繼承關系:

    6.字符輸入流(Reader)

    1.關于Reader
    所在位置:java.io.Reader
    簡介:字符輸入流的所有類的超類

    2.字符輸入流的常用方法:

    方法名方法作用
    public void close() :關閉此流并釋放與此流相關聯的任何系統資源
    public int read()從輸入流讀取一個字符
    public int read(char[] cbuf)從輸入流中讀取一些字符,并將它們存儲到字符數組 cbuf中

    以上三個方法則是字符輸入流都具有的方法,由父類Reader定義提供,子類都會共享以上方法

    3.FileReader類
    (1)FileReader類概述:
    由于Reader是一個抽象類無法實例化對象,那么就需要Reader的子類,FileReader是其的一個子類,是讀取字符文件的便利類,構造時使用系統默認的字符編碼和默認字節緩沖區

    (2)構造方法:

    1.FileReader(File file): 創建一個新的 FileReader ,給定要讀取的File對象
    2.FileReader(String fileName): 創建一個新的 FileReader ,給定要讀取的文件的字符串名稱

    (3)FileReader的使用:

    類和FileInputStream類和FileReader用法完全類似包括兩種read讀取和String解碼,只是讀取的單位不同而已

    例子:

    package untl1; import java.io.FileReader; import java.io.IOException; public class MyFile {public static void main(String[] args) throws IOException {FileReader file1=new FileReader("d:1\\c.txt");int len;while((len=file1.read())!=-1){System.out.println((char)len);}FileReader file2=new FileReader("d:1\\c.txt");int lenn;char arr[]=new char[1024];//注意這里的字符串是charwhile((lenn=file2.read(arr))!=-1){System.out.println(new String(arr));//這里得到new String是把字符數組轉換成字符串,//也可以使用三個參數的,用法與前面的一樣}file1.close();file2.close();} } 運行結果: 誰 還 不 是 個 野 王 誰還不是個野王

    c.txt內容:

    7.字符輸出流(Writer)

    1.關于Writer
    所在位置:java.io.Writer
    簡介:是字符輸入流的所有類的超類(父類),可以讀取字符信息到內存中。它定義了字符輸入流的基本共性功能方法。

    2.字符輸出流的常用方法:

    方法名作用
    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()關閉此流,但要先刷新它

    以上七個方法則是字符輸出流都具有的方法,由父類Writer定義提供,子類都會共享以上方法

    3.FileWriter類
    (1)FileWriter類概述:
    由于Writer是一個抽象類無法實例化對象,那么就需要Writer的子類,FileWriter是其的一個子類,是寫出字符到文件的便利類。構造時使用系統默認的字符編碼和默認字節緩沖區。

    (2)構造方法:

    1、FileWriter(File file): 創建一個新的 FileWriter,給定要讀取的File對象。
    2、FileWriter(String fileName): 創建一個新的 FileWriter,給定要讀取的文件的名稱。

    (3)FileWriter的使用:
    例子:

    package untl1; import java.io.FileWriter; import java.io.IOException; public class MyFile {public static void main(String[] args) throws IOException {FileWriter file1=new FileWriter("d:1\\c.txt");file1.write(98);file1.write("我是弟弟");file1.close();} } 運行結果 c.txt里邊寫進:a我是弟弟

    注意:關閉資源時,與FileOutputStream不同。 如果不關閉,數據只是保存到緩沖區,并未保存到文件。想要保存到緩沖區就必須關閉資源或者刷新該流的緩沖(就是flush方法)

    (4)關閉close和刷新flush
    兩者的區別:

    flush:刷新緩沖區,流對象可以繼續使用。
    close:先刷新緩沖區,然后通知系統釋放資源。流對象不可以再被使用了。
    flush()這個函數是清空的意思,用于清空緩沖區的數據流,進行流的操作時,數據先被讀到內存中,然后再用數據寫到文件中,那么當你數據讀完時,我們如果這時調用close()方法關閉讀寫流,這時就可能造成數據丟失,為什么呢?因為,讀入數據完成時不代表寫入數據完成,一部分數據可能會留在緩存區中,這個時候flush()方法就格外重要了。即便是flush方法寫出了數據,操作的最后還是要調用close方法,釋放系統資源。

    (5)FileWriter的續寫和換行和前面的字節流續寫和換行一樣的

    8. Properties類詳解

    (1)Properties概述
    是一種java配置文件的類,java.util.Properties繼承于Hashtable,來表示一個持久的屬性集(所以自己也是一個集合)。它使用鍵值結構存儲數據,每個鍵及其對應值都是一個字符串。

    (2)Properties常用方法:

    常用方法名作用
    public Object setProperty(String key, String value)保存一對屬性
    public String getProperty(String key)使用此屬性列表中指定的鍵搜索屬性值
    public Set stringPropertyNames()返回所有鍵的名稱的Set集合

    (3)Properties常用方法的使用實例:
    例子1:

    package untl1; import java.util.Properties; import java.util.Set; public class MyProperties {public static void main(String[] args) {//創建Properties集合對象Properties myProperties=new Properties();//使用setProperty往集合里邊添加元素myProperties.setProperty("劉備","170");myProperties.setProperty("關羽","180");myProperties.setProperty("張飛","175");//使用stringPropertyNames方法把Properties中的鍵值取出來,存儲到Set集合里Set<String> set=myProperties.stringPropertyNames();for (String key:set){//使用getProperty把鍵對應的值取出來String value=myProperties.getProperty(key);System.out.println(key+"="+value);}} } 運行結果: 劉備=170 關羽=180 張飛=175

    (4)Properties類中store方法:

    1.public void store(Writer writer, String comments)
    2.public void store(OutputStream out, String comments)
    這里注意用第一種store方法可以把集合里的中文寫進去,但是第二種寫入方式不能把集合里邊的中文寫進去,第二個參數用來解釋保存文件是做什么的,不能使用中文,會參生亂碼,默認為Unicode編碼一般都傳的是空字符串“”

    方法的作用:把Properties集合里邊的臨時數據持久化寫入磁盤中存儲

    使用步驟:

    • 1.創建Properties集合對象,添加數據
    • 2.創建字節/字符輸出流對象,構造方法綁定要寫進的目的地
    • 3.使用 Properties集合中的方法store把集合里邊的臨時數據持久化寫入磁盤中存儲
    • 4.釋放資源
    例子: package untl1; import java.io.FileWriter; import java.io.IOException; import java.util.Properties; public class MyProperties {public static void main(String[] args) throws IOException {Properties myProperties=new Properties();myProperties.setProperty("劉備","170");myProperties.setProperty("關羽","180");Object 張飛 = myProperties.setProperty("張飛", "175");FileWriter fw=new FileWriter("d:1\\c.txt");//c.txt是一個空白文件myProperties.store(fw,"");fw.close();} }

    運行結果(c.txt變化如下):

    第一行是對寫的東西進行解釋,由于傳進的是一個空的字符串所有沒有內容
    第二行是默認加的寫入時間
    之后就是集合里邊的內容

    (5)Properties類中load方法:

    1.public void load(InputStream inStream)
    2.public void load(Reader reader)
    參數的解釋:
    InputStream inStream:字節輸入流,不能讀取含有中文的鍵值對
    Reader reader:字符輸入流,能讀取含中文的鍵值對

    使用步驟:

    • 1.創建Properties集合對象
    • 2.使用Properties集合對象中的load方法讀取保存鍵值對的文件
    • 3.遍歷集合

    例子:

    package untl1; import java.io.FileReader; import java.io.IOException; import java.util.Properties; import java.util.Set; public class MyProperties {public static void main(String[] args) throws IOException {Properties myProperties=new Properties();FileReader file1=new FileReader("d:\\1\\c.txt");//里邊保存第(4)點寫進的內容myProperties.load(file1);Set<String> set=myProperties.stringPropertyNames();for (String key:set){System.out.println(key+"="+myProperties.getProperty(key));}} } 運行結果: 劉備=170 關羽=180 張飛=175

    1.存儲鍵值對的文件中,鍵與值的連接符號可以使用=,空格或者其他符號
    2.存儲文件中,可以使用#進行注解,注解的鍵值對不會被讀取
    3.存儲價值對的文件中,鍵與值都是字符串不用加引號

    9. 緩沖流概述

    由于四個基本流(FileInputStream,FileOutputStream,FileReader,FileWriter)的效率比較低,體現在我們多次讀寫文件的時候都要對原始數據多次訪問,每次對原始數據的訪問都會有
    java程序——》java虛擬機——》操作系統——》操作系統調用讀寫操作,顯得太麻煩,緩沖流就是在第一次訪問時就把要讀或者要寫的內容存在一個數組中(這個數組就是緩沖流的根本),那么當我們二次訪問時候就可以直接在數組里進行操作

    專業點來講就是:緩沖流把數據從原始流成塊讀入或把數據積累到一個大數據塊后再成批寫出,通過減少通過資源的讀寫次數來加快程序的執行。

    字節緩沖流:BufferedInputStream,BufferedOutputStream
    字符緩沖流:BufferedReader,BufferedWriter
    是對四個基本流的加強版

    再來看一下四種緩沖流的繼承關系;

    10.字節緩沖流(BufferedInputStream,BufferedOutputStream)

    1.字節緩沖輸出流(BufferedOutputStream)
    (1)構造方法:

    1.public BufferedOutputStream(OutputStream out) :創建一個新的緩沖輸入流,注意參數類型為InputStream。
    2.public BufferedOutputStream(OutputStream out,int size): 創建一個新的緩沖輸出流,注意size就是自定義緩沖流的數組,不指定就是默認的大小

    (2)使用步驟

    • 1.創建FileOutputStream對象,構造方法中綁定要輸出的目的地
    • 2.創建BufferedOutputStream對象,構造方法為FileFileOutputStream對象,提高FileOutputStream的效率
    • 3.使用BufferedOutputStream對象的writer方法,把數據寫入內部緩沖區里邊
    • 4.使用BufferedOutputStream里邊的flush方法,把內部緩沖區里邊的數據刷新到文件里
    • 5.釋放資源

    例子:

    package untl1; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class MyProperties {public static void main(String[] args)throws IOException {FileOutputStream file1=new FileOutputStream("d:1\\c.txt");//c.txt是空的文件BufferedOutputStream bos=new BufferedOutputStream(file1);String str="我是哥哥";byte arr[]=str.getBytes();bos.write(arr);bos.flush();bos.close();} } 運行結果: c.txt文件寫進了我是哥哥

    2.字節緩沖輸入流(BufferedInputStream)
    (1)構造方法:

    1.public BufferedInputStream(InputStream in) :創建一個新的緩沖輸入流,注意參數類型為InputStream
    2.public BufferedInputStream(InputStream in,int size) ::創建一個新的緩沖輸入流,size作用同上

    (2)使用步驟:

    • 1.創建FileInputStream對象,構造方法中綁定要讀取的數據源
    • 2.創建BufferedInputStream對象,構造方法中傳遞FileInputStream對象,提高FileInputStream對象的讀取效率
    • 3.使用BufferedInputStream中的方法read方法讀文件
    • 4.釋放資源
    例子: package untl1; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class MyProperties {public static void main(String[] args)throws IOException {FileInputStream file1=new FileInputStream("d:1\\c.txt");//里邊就一句話"我是哥哥"BufferedInputStream bis=new BufferedInputStream(file1);byte[] arr=new byte[3];int len=0;while((len=bis.read(arr))!=-1){System.out.println(new String(arr));}} } 運行結果: 我 是 哥 哥

    11.字符緩沖流(BufferedReader,BufferedWriter)

    1.字符緩沖輸出流
    (1)構造方法:

    1.public BufferedWriter(Writer out):創建一個新的緩沖輸入流,注意參數類型為Reader
    2.public BufferedWriter(Writer out,int sz):創建一個新的緩沖輸入流,sz作用同上

    (2)使用步驟:

    • 1.創建字符輸出流對象,構造方法中傳遞字符輸出流對象
    • 2.調用字符緩沖輸出流的writer方法,把數據吸入內存緩沖區
    • 3.調用字符緩沖輸出流的flush方法,把內存緩沖區的數據刷新到文件中
    • 4.釋放資源

    例子:

    package untl1; import java.io.*; public class MyProperties {public static void main(String[] args)throws IOException {FileWriter fw=new FileWriter("d:1\\c.txt");BufferedWriter bf=new BufferedWriter(fw);String str="我是弟弟";bf.write(new String(str));bf.flush();bf.close();} } 運行結果: 把我是弟弟寫進c.txt文件

    (3)BufferedWriter特有的方法

    public void newLine(): 換行,由系統屬性定義符號
    我們以前寫數據的時候把“\r\n”寫進文件就會換行,但是這里可以直接調用這個方法就能實現換行

    2.字符緩沖輸入流
    (1)構造方法:

    1.public BufferedReader(Reader in):創建一個新的緩沖輸入流,注意參數類型為Reader
    2.public BufferedReader(Reader in,int sz):創建一個新的緩沖輸入流,sz作用同上

    (2)使用步驟:

    • 1.創建字符緩沖輸入流對象,構造方法中傳遞字符輸入流
    • 2.使用字符緩沖輸入流對象的read方法讀取文本
    • 3.釋放資源
    例子: package untl1; import java.io.*; public class MyProperties {public static void main(String[] args)throws IOException {FileReader fr=new FileReader("d:1\\c.txt");//c.txt里只有一句話:我是弟弟BufferedReader bf=new BufferedReader(fr);char arr[]=new char[5];int len=0;while((len=bf.read(arr))!=-1){System.out.println(new String(arr,0,len));}bf.close();} } 運行結果: 我是弟弟

    (3)BufferedReader特有的方法

    public String readLine(): 讀一行數據。 讀取到最后返回null

    例子:

    package untl1; import java.io.*; public class MyProperties {public static void main(String[] args)throws IOException {FileReader fr=new FileReader("d:1\\c.txt");BufferedReader bf=new BufferedReader(fr);String str1=bf.readLine();System.out.println(str1);String str2=bf.readLine();System.out.println(str2);} } 運行結果: 我是弟弟 null

    12.緩沖流高效率測試

    緩沖流有多高效呢,接下來我們來測試一下,博主把d:0.jpg復制到d:1\\0.copy.jpg,分別用普通流和緩沖流進行比較:
    普通流:

    package untl1; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class MyProperties {public static void main(String[] args)throws IOException {long begin=System.currentTimeMillis();FileInputStream fis=new FileInputStream("d:0.jpg");FileOutputStream fos=new FileOutputStream("d:1\\0copy.jpg");int len=0;while((len=fis.read())!=-1){fos.write(len);}fos.close();fis.close();long end=System.currentTimeMillis();System.out.println("整個過程耗時"+(end-begin)+"毫秒");} } 運行結果: 整個過程耗時46毫秒

    緩沖流:

    package untl1; import java.io.*; public class MyProperties {public static void main(String[] args)throws IOException {long begin=System.currentTimeMillis();FileInputStream fis=new FileInputStream("d:0.jpg");FileOutputStream fos=new FileOutputStream("d:1\\0copy.jpg");BufferedInputStream bis=new BufferedInputStream(fis);BufferedOutputStream bos=new BufferedOutputStream(fos);int len=0;while((len=bis.read())!=-1){bos.write(len);}bos.flush();bos.close();fis.close();long end=System.currentTimeMillis();System.out.println("整個過程耗時"+(end-begin)+"毫秒");} } 運行結果: 整個過程耗時3毫秒

    結論:你品,你細品

    13.轉換流概述

    (1)亂碼問題:

    在介紹轉換流之前,不知道大家有沒有遇到一個問題
    使用FileReader或者OutputStream讀取txt文件,明明寫的代碼是正確的但是卻讀到一堆亂碼,.

    例子:

    ```cpp package untl1; import java.io.FileReader; import java.io.IOException; public class MyFile {public static void main(String[] args) throws IOException {FileReader file1=new FileReader("d:1\\c.txt");//里邊是幾個漢字int len;while((len=file1.read())!=-1){System.out.println((char)len);}FileReader file2=new FileReader("d:1\\c.txt");int lenn;char arr[]=new char[1024];while((lenn=file2.read(arr))!=-1){System.out.println(new String(arr));}file1.close();file2.close();} } 運行結果: ���

    為啥呢,往下看

    (2)字符編碼和解碼:

    我們知道,計算機中儲存的數據都是用二進制數表示的,而我們在屏幕上看到的數字、英文、標點符號、漢字等字符是二進制數轉換之后的結果。按照某種規則,將字符存儲到計算機中,稱為編碼 。反之,將存儲在計算機中的二進制數按照某種規則解析顯示出來,稱為解碼 。比如說,按照A規則存儲,同樣按照A規則解析,那么就能顯示正確的文本符號。反之,按照A規則存儲,再按照B規則解析,就會導致亂碼現象。所以開頭的問題就已經明確,當我們使用FileReader或者InputStream進行字符的讀取的時候,解碼時默認為utf-8,我們電腦txt文件默認編碼用ASCII,所以我們只需要改變編碼的方式為utf-8就能把漢字正確的讀取出來(打開文件然后選擇另存為就可以選擇編碼方式如下圖)

    編碼和解碼簡單來說:

    編碼:字符(能看懂的)------》字節(看不懂的)
    解碼:字節(看不懂的)------》字符(能看懂的)

    (3)字符編碼和編碼表

    1.字符編碼: 就是一套自然語言的字符與二進制數之間的對應規則。
    2.z字符集(也叫編碼表):是生活中文字和計算機中二進制的對應規則

    字符集的分類:

    字符集字符集解析
    ASCII字符集
    • ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼)是基于拉丁字母的一套電腦編碼系統,用于顯示現代英語,主要包括控制字符(回車鍵、退格、換行鍵等)和可顯示字符(英文大小寫字符、阿拉伯數字和西文符號)。
    • 基本的ASCII字符集,使用7位(bits)表示一個字符,共128字符。ASCII的擴展字符集使用8位(bits)表示一個字符,共256字符,方便支持歐洲常用字符。
    ISO-8859-1字符集:
    • 拉丁碼表,別名Latin-1,用于顯示歐洲使用的語言,包括荷蘭、丹麥、德語、意大利語、西班牙語等
    • ISO-8859-1使用單字節編碼,兼容ASCII編碼
    GBxxx字符集
    • GB就是國標的意思,是為了顯示中文而設計的一套字符集。
    • GB2312:簡體中文碼表。一個小于127的字符的意義與原來相同。但兩個大于127的字符連在一起時,就表示一個漢字,這樣大約可以組合了包含7000多個簡體漢字,此外數學符號、羅馬希臘的字母、日文的假名們都編進去了,連在ASCII里本來就有的數字、標點、字母都統統重新編了兩個字節長的編碼,這就是常說的"全角"字符,而原來在127號以下的那些就叫"半角"字符了。
    • GBK:最常用的中文碼表。是在GB2312標準基礎上的擴展規范,使用了雙字節編碼方案,共收錄了21003個漢字,完全兼容GB2312標準,同時支持繁體漢字以及日韓漢字等。
    • GB18030:最新的中文碼表。收錄漢字70244個,采用多字節編碼,每個字可以由1個、2個或4個字節組成。支持中國國內少數民族的文字,同時支持繁體漢字以及日韓漢字等。
    Unicode字符集
    • Unicode編碼系統為表達任意語言的任意字符而設計,是業界的一種標準,也稱為統一碼、標準萬國碼。
    • 它最多使用4個字節的數字來表達每個字母、符號,或者文字。有三種編碼方案,UTF-8、UTF-16和UTF-32。最為常用的UTF-8編碼。
    • UTF-8編碼,可以用來表示Unicode標準中任何字符,它是電子郵件、網頁及其他存儲或傳送文字的應用中,優先采用的編碼。互聯網工程工作小組(IETF)要求所有互聯網協議都必須支持UTF-8編碼。所以,我們開發Web應用,也要使用UTF-8編碼。它使用一至四個字節為每個字符編碼,編碼規則:128個US-ASCII字符,只需一個字節編碼。拉丁文等字符,需要二個字節編碼。大部分常用字(含中文),使用三個字節編碼。其他極少使用的Unicode輔助字符,使用四字節編碼。

    14. InputStreamReader類和 OutputStreamWriter類

    1.InputStreamReader類
    (1) 轉換流java.io.InputStreamReader,是Reader的子類,從字面意思可以看出它是從字節流到字符流的橋梁。它讀取字節,并使用指定的字符集將其解碼為字符。它的字符集可以由名稱指定,也可以接受平臺的默認字符集。
    (2)構造方法:

    1.InputStreamReader(InputStream in): 創建一個使用默認字符集的字符流。
    2.InputStreamReader(InputStream in, String charsetName): 創建一個指定字符集的字符流。指定的字符集大小寫不限

    (3)使用步驟:

    • 1.創建InputStreamReader對象,構造方法中傳遞字節輸入流和指定的編碼表的名稱
    • 2.使用InputStreamReader里邊的read方法讀取文件
    • 3.釋放資源

    例子:

    package untl1; import java.io.*; public class MyProperties {public static void main(String[] args)throws IOException {FileInputStream fis=new FileInputStream("d:1\\c.txt");InputStreamReader isr=new InputStreamReader(fis,"utf-8");int len=0;while((len=isr.read())!=-1){System.out.println((char)len);}isr.close();} } 運行結果: 把c.txt文件里的內容按照utf-8標準解析出來

    注意InputStreamReader構造方法傳進的是字節輸出流

    2.OutputStreamWriter類
    (1)轉換流java.io.OutputStreamWriter ,是Writer的子類,字面看容易混淆會誤以為是轉為字符流,其實不然,OutputStreamWriter為從字符流到字節流的橋梁。使用指定的字符集將字符編碼為字節。它的字符集可以由名稱指定,也可以接受平臺的默認字符集。

    (2)構造方法:

    1.OutputStreamWriter(OutputStream in): 創建一個使用默認字符集的字符流。
    2.OutputStreamWriter(OutputStream in, String charsetName): 創建一個指定字符集的字符流。指定的字符集大小寫不限

    (3)使用步驟:

    • 1.創建OutputStreamWriter對象構造方法中傳遞字節輸出流和指定的編碼表名稱
    • 2.使用OutputStreamWriter對象中的writer方法,把字符轉換為字節存放在緩沖區
    • 3.使用OutputStreamWriter對象中的flush方法,把緩沖區的內容打印到文件上
    • 4.釋放資源

    例子:

    package untl1; import java.io.*; public class MyProperties {public static void main(String[] args)throws IOException {FileOutputStream fos=new FileOutputStream("d:1\\c.txt");OutputStreamWriter osw=new OutputStreamWriter(fos,"utf-8");String str="我是咯咯";osw.write(str);osw.flush();osw.close();} }

    注意OutputStreamWriter構造方法傳進的是字節輸入流

    15.序列化

    1.序列化概述
    (1)序列化的含義和意義:
    序列化機制允許將實現序列化的Java對象轉換成字節序列,這些字節序列可以保存在
    磁盤上,或通過網絡傳輸,以備以后重新恢復成原來的對象。序列化機制使得對象可
    以脫離程序的運行而獨立存在。對象的序列化(Serialize)指將一個Java對象寫入IO流中,與此對應的是,對象的反序列化(Deserialize)則指從IO流中恢復該Java對象如果需要讓某個對象支持序列化
    機制,則必須讓它的類是可序列化的

    (2)序列化和反序列化

    序列化:Java 提供了一種對象序列化的機制。用一個字節序列可以表示一個對象,該字節序列包含該對象的數據、對象的類型和對象中存儲的屬性等信息。字節序列寫出到文件之后,相當于文件中持久保存了一個對象的信息。
    反序列化:把字節序列還可以從文件中讀取回來,重構對象,稱為反序列化。對象的數據、對象的類型和對象中存儲的數據信息,都可以用來在內存中創建對象。


    2. ObjectOutputStream類
    (1)java.io.ObjectOutputStream 類也叫對象的序列化流,將Java對象的原始數據類型寫出到文件,實現對象的持久存儲。

    雖然ObjectOutputStream是一個對象的序列化流,但是想要使一個對象序列化還要兩個條件:

    1.對象所屬類類必須實現java.io.Serializable 接口(當實現此接口后,就會個給類添加一個標記,如果有的化可以進行序列化和反序列化操作,沒有的話拋出異常)
    2.對象所屬類的所有屬性必須是可序列化的。如果有一個屬性不需要可序列化的,則該屬性必須注明是瞬態的,使用transient 關鍵字修飾。靜態成員(static)是不能被序列化的

    (2)構造方法和特有的方法:

    1.構造方法:public ObjectOutputStream(OutputStream out):構造方法傳遞字節輸出流
    2.特有的方法:void writeObject(Object obj):將指定的對象寫入序列化流中

    (3)ObjectOutputStream的使用步驟:

    • 1.創建ObjectOutputStream對象,構造方法傳遞字節輸出流
    • 2.使用ObjectOutputStream對象中的writerObject方法,把對象寫入文件
    • 3.釋放資源
    例子: package untl1; import java.io.*; public class MyProperties {public static void main(String[] args) throws IOException{FileOutputStream fos=new FileOutputStream("d:1\\c.txt");//c.txt是一個空白文檔ObjectOutputStream oos=new ObjectOutputStream(fos);perosn per=new perosn();oos.writeObject(per);oos.flush();} } class perosn implements Serializable{private int a;private static int b=12;private transient int c;perosn(){this.a=10;b=100;this.c=1000;}public String toString(){System.out.println("a="+a);System.out.println("b="+b);System.out.println("c="+c);return "";} }

    3 . ObjectInputStream類

    (1)java.io.ObjectInputStream反序列化流,將之前使用ObjectOutputStream序列化的原始數據恢復為對象。

    (2)構造方法和特有的方法:

    1.構造方法:public ObjectInputStream(InputStream in): 注意傳遞的是字節輸入流
    2.特有方法:public final Object readObject () : 讀取一個對象。

    (3)使用步驟:

    • 1.創建ObjectInputStream對象,構造方法傳入字節輸入流
    • 2.使用ObjectInputStream對象中的方法readObject讀取保存對象的文件
    • 3.釋放資源
    • 4.使用讀取的對象

    例子:

    package untl1; import java.io.*; public class MyProperties {public static void main(String[] args) throws IOException,ClassNotFoundException{FileInputStream fis=new FileInputStream("d:1\\c.txt");//只有上一個例子寫入的一個對象ObjectInputStream ois=new ObjectInputStream(fis);Object obj=ois.readObject();ois.close();System.out.println(obj);} } class perosn implements Serializable{private int a;private static int b=12;private transient int c;perosn(){this.a=10;b=100;this.c=1000;}public String toString(){System.out.println("a="+a);System.out.println("b="+b);System.out.println("c="+c);return "";} } 運行結果: a=10 b=12 c=0

    這個運行結果就印證了
    如果有一個屬性不需要可序列化的,則該屬性必須注明是瞬態的,使用transient 關鍵字修飾。靜態成員(static)是不能被序列化的

    (4)注意事項:

    1.對于JVM可以反序列化對象,它必須是能夠找到class文件的類。如果找不到該類的class文件,則拋出一個 ClassNotFoundException 異常。
    2.JVM反序列化對象時,能找到class文件,但是class文件在序列化對象之后發生了修改(就是在反序列化之前修改了類),那么反序列化操作也會失敗,拋出一個InvalidClassException異常。

    16.打印流

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

    2.PrintStream類

    (1)構造方法:

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

    (2)PrintStream的特點:

    1.只負責數據的輸出,不負責數據的讀取
    2.與其他輸入流不同·, PrintStream不會拋出IOException異常
    3.有特有的方法print或println,注意沒有printf

    (3)PrintStream的使用

    1.PrintStream繼承OutputStream類
    2.如果使用繼承來自父類的write方法寫數據那么寫入數據的時候會查詢碼表
    3.如果使用自己特有的方法print或者println方法寫數據,則會原樣輸出

    例子:

    package untl1; import java.io.FileNotFoundException; import java.io.PrintStream; public class MyProperties {public static void main(String[] args) throws FileNotFoundException {PrintStream ps=new PrintStream("D:1\\c.txt");//c.txt是空白文件ps.print(97);ps.write(97);} } 運行結果: 在c.txt文件里的第一行內容為:a97

    打印流還有更神奇的操作,那就是改變輸出語句的目的地(打印流的流向)System.setOut方法改變輸出語句的目的地為參數中傳遞的打印流的目的地

    static void setOut(PrintStream our):重新分配標準輸出流

    例子:

    package untl1; import java.io.FileNotFoundException; import java.io.PrintStream; public class MyProperties {public static void main(String[] args) throws FileNotFoundException {PrintStream ps=new PrintStream("D:1\\c.txt");//c.txt是空文件System.out.println("heello world");System.setOut(ps);System.out.println("哈哈哈");} } 運行結果: hello world

    哈哈哈則是被輸出到c.txt文件中

    總結

    以上是生活随笔為你收集整理的三万字的java I/O流基础总结看完肯定能把女朋友教会的全部內容,希望文章能夠幫你解決所遇到的問題。

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