【Java】关于Java中的各种流
1 IO流
1.1 概念
input:輸入(讀取)-----> 流:數(shù)據(jù)(字節(jié)/字符) -----> output:輸出(寫入)
輸入:把硬盤中的數(shù)據(jù),讀取到內(nèi)存中使用
輸出:把內(nèi)存中的數(shù)據(jù),寫入到硬盤中保存
內(nèi)存:臨時(shí)存儲(chǔ)
硬盤:永久存儲(chǔ)
1個(gè)字符 = 2個(gè)字節(jié)
1個(gè)字節(jié)=8個(gè)二進(jìn)制位
頂層父類
| 字節(jié)流 | 字節(jié)輸入流 InputStream | 字節(jié)輸出流 OutputStream |
| 字符流 | 字符輸入流 Reader | 字符輸出流 Writer |
2 字節(jié)流
2.1 字節(jié)輸出流OutputStream
它是一個(gè)抽象類
共性成員方法:
2.1.1 文件字節(jié)輸出流FileOutputStream
,extends OutputStream,把內(nèi)存中的數(shù)據(jù)寫入硬盤的文件中。
構(gòu)造方法:創(chuàng)建一個(gè) FileOutputStream 對(duì)象。根據(jù)參數(shù)傳遞的文件/文件路徑,創(chuàng)建一個(gè)空文件。把 FileOutputStream 對(duì)象指向創(chuàng)建好的文件。
寫入數(shù)據(jù)的原理(內(nèi)存 —> 硬盤)
Java程序 —> JVM —>OS —> OS調(diào)用寫數(shù)據(jù)的方法 —>把數(shù)據(jù)寫入文件中
字節(jié)輸出流的使用步驟
把a(bǔ)寫入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();}原理:寫數(shù)據(jù)時(shí)會(huì)把十進(jìn)制97轉(zhuǎn)為二進(jìn)制1100001?,硬盤中存儲(chǔ)的數(shù)據(jù)都是字節(jié),1個(gè)字節(jié)等于8個(gè)比特位。文本編輯器在打開文件時(shí)會(huì)查詢編碼表,把字節(jié)轉(zhuǎn)為字符表示,97—>a。
一次寫入多個(gè)字節(jié)
public void write(byte[] b)
public void write(byte[] b, int off, int len) :把數(shù)組的一部分寫入文件
使用String類的方法把字符串轉(zhuǎn)換為字節(jié)數(shù)組。
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:兩個(gè)字節(jié)是一個(gè)中文
UTF8:三個(gè)字節(jié)是一個(gè)中文
數(shù)據(jù)的追加寫和換行寫
追加寫的構(gòu)造方法 append=true
FileOutputStream(String name, boolean append)
FileOutputStream(File file, boolean append)
換行:win【\r\n】mac【/n】linux【/r】
2.2 字節(jié)輸入流InputStream
它是一個(gè)抽象類,是所有字節(jié)輸入流類的超類
共性方法
- int read()
- int read(byte[] b)
- void close
2.2.1 文件字節(jié)輸入流FileInputStream
作用:把硬盤中的數(shù)據(jù),讀取到內(nèi)存中使用
構(gòu)造方法
- FileInputStream(String name)
- FileInputStream(File file)
構(gòu)造方法的作用:
讀取數(shù)據(jù)原理(硬盤—>內(nèi)存)
Java程序 —> JVM —>OS —>OS調(diào)用讀取數(shù)據(jù)的方法 —> 讀取文件
字節(jié)輸出流的使用步驟
注意:read每調(diào)用一次指針都會(huì)后移一位,如果while循環(huán)括號(hào)中不保存讀取的值,輸出的就是跳位讀取的值。
一次讀取一個(gè)字節(jié)
public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");int len = 0;while((len = fis.read())!=-1){//讀取一個(gè)字節(jié)并返回 文件末尾返回-1System.out.print((char) len);}fis.close();}一次讀取多個(gè)字節(jié)
int read(byte[] b):
注意:byte[]的作用是起緩沖作用,存儲(chǔ)每次讀取到的多個(gè)字節(jié)。數(shù)組長度一般定義為1024(1kb)或者1024的整數(shù)值。int返回值是每次讀取的有效字節(jié)個(gè)數(shù)。
原理:創(chuàng)建一個(gè)byte數(shù)組,數(shù)組元素的初始值為0。開始讀取,把讀取出的數(shù)據(jù)存入byte數(shù)組,指針移動(dòng),b.length是一次讀取的字節(jié)個(gè)數(shù)。new String()可以把byte數(shù)組轉(zhuǎn)換為字符串輸出。read方法的返回值是有效讀取字節(jié)個(gè)數(shù)。
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 字節(jié)流練習(xí)-文件復(fù)制
原理
創(chuàng)建一個(gè)輸入流的對(duì)象,再創(chuàng)建一個(gè)輸出流的對(duì)象,然后輸入流對(duì)象讀取文件內(nèi)容,寫入輸出流指向的對(duì)象處。
注意:應(yīng)該先關(guān)閉輸出流(寫),再關(guān)閉輸入流(讀)。因?yàn)閷懲炅艘欢ㄗx完了,但讀完了不一定寫完了。應(yīng)該先開啟輸入流,再開啟輸出流,先讀后寫。
2.4 字節(jié)流讀文件存在的問題
在讀取中文字符的時(shí)候,可能不會(huì)顯示完整的字符,因?yàn)橐粋€(gè)中文可能占用多個(gè)字節(jié)。按字節(jié)流讀取,每次只能讀取字符的一部分。所以文本文件一般用字符流進(jìn)行讀寫。
GBK:1個(gè)中文2個(gè)字節(jié)
UTF8:1個(gè)中文3個(gè)字節(jié)
3 字符流
3.1 字符輸入流Reader
字符輸入流類最頂層的父類,是一個(gè)抽象類。
共性方法
- int read()
- int read(char[] c)
- void close()
3.1.1 文件字符輸入流FileReader
作用:把硬盤文件中的數(shù)據(jù)以字符的方式讀取到內(nèi)存中
構(gòu)造方法:創(chuàng)建一個(gè)FileReader對(duì)象,把FileReader對(duì)象指向要讀取的文件/文件路徑
- FileReader(String name)
- FileReader(File file)
使用步驟
一次讀取一個(gè)字符
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();}一次讀取多個(gè)字符
字符數(shù)組 —> 字符串 new String(char[], int off, int len)構(gòu)造方法
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) 寫入單個(gè)字符。
- void write(char[] cbuf) 寫入字符數(shù)組。
- abstract void write(char[] cbuf, int off, int len) 寫入字符數(shù)組的某一部分,off數(shù)組的開始索引,len寫的字符個(gè)數(shù)。
- void write(String str) 寫入字符串。
- void write(String str, int off, int len) 寫入字符串的某一部分,off字符串的開始索引,len寫的字符個(gè)數(shù)。
- void flush() 刷新該流的緩沖。
- void close() 關(guān)閉此流,但要先刷新它。
3.2.1 文件字符輸出流FileWriter
作用:內(nèi)存中的字符數(shù)據(jù)寫入文件中
構(gòu)造方法
- FileWriter(String name)
- FileWriter(File file)
作用:創(chuàng)建FileWriter對(duì)象,根據(jù)構(gòu)造方法中傳遞的文件/文件路徑創(chuàng)建文件,會(huì)把FileWriter對(duì)象指向創(chuàng)建好的文件中。
使用步驟
寫入單個(gè)字符
public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("a.txt");//綁定寫入位置fw.write(97);//寫入緩沖區(qū) 字符-->字節(jié)fw.flush();//寫入文件fw.close();//釋放資源}flush和close方法的區(qū)別
close在關(guān)閉之前會(huì)先把內(nèi)存緩沖區(qū)的數(shù)據(jù)刷新到文件中,但close之后不能繼續(xù)使用write方法。flush同樣也是刷新操作,但flush之后可以繼續(xù)使用write方法。
其他寫入方法
- void write(char[] c):寫入字符數(shù)組
- abstract void write(char[] c, int off, int len):寫入字符數(shù)組的某一部分
- void write(String str):寫入字符串
- void write(String str, int off, int len):寫入字符串的某一部分
續(xù)寫和換行寫
同字節(jié)流輸出
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后增加一個(gè)()( )(),括號(hào)中可以定義流對(duì)象,那么這個(gè)流對(duì)象的作用域就在try中有效,try執(zhí)行完后,流對(duì)象自動(dòng)釋放,不用寫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前面可以定義對(duì)象,在try后邊的()中可以引入流對(duì)象的名稱。try執(zhí)行完畢后,流對(duì)象可以釋放掉,不需要寫finally?!静怀S谩?/p> 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,來表示一個(gè)持久的屬性集。是唯一一個(gè)和IO流相結(jié)合的集合。
它使用鍵值結(jié)構(gòu)存儲(chǔ)數(shù)據(jù),每個(gè)鍵及其對(duì)應(yīng)值都是一個(gè)字符串。該類也被許多Java類使用,比如獲取系統(tǒng)屬性時(shí), System.getProperties 方法就是返回一個(gè)Properties 對(duì)象。
使用Properties存儲(chǔ)數(shù)據(jù)并遍歷取出
操作字符串的特有方法
- Object setProperty(String key, String value):相當(dāng)于map.put(k, v)
- String getProperty(String key):相當(dāng)于map.get(k)
- Set <String> stringPropertyNames():相當(dāng)于map.keySet()
- 可以使用store方法把集合中的臨時(shí)數(shù)據(jù),持久化寫入硬盤中存儲(chǔ)
- void store(OutputStream out, String comments):字節(jié)輸出流,不能寫中文。
- void store(Writer writer, String comments):字符輸出流,可以寫中文。
comments是注釋,用來解釋保存的文件是做什么的,不可以使用中文,默認(rèn)是Unicode編碼,一般使用空字符串
使用步驟
- 可以使用load方法,把硬盤中保存的文件,讀取到集合中使用
- void load(InputStream in):字節(jié)輸入流,不能讀取含有中文的鍵值對(duì)
- void load(Reader r):字符輸入流,可以讀取含有中文的鍵值對(duì)
使用步驟
注意
- 鍵值對(duì)文件中,鍵和值默認(rèn)的連接符可以使用=、空格
- 可以使用#來注釋,被注釋的鍵值對(duì)不會(huì)再讀取
- 鍵和值默認(rèn)都是字符串,不用再加引號(hào)
6 緩沖流
緩沖流,也叫高效流,是對(duì)4個(gè)基本的FileXxx 流的增強(qiáng),所以也是4個(gè)流,按照數(shù)據(jù)類型分類:
字節(jié)緩沖流: BufferedInputStream , BufferedOutputStream
字符緩沖流: BufferedReader , BufferedWriter
緩沖流的基本原理,是在創(chuàng)建流對(duì)象時(shí),會(huì)創(chuàng)建一個(gè)內(nèi)置的默認(rèn)大小的緩沖區(qū)數(shù)組,通過緩沖區(qū)讀寫,減少系統(tǒng)IO次數(shù),從而提高讀寫的效率。
6.1 字節(jié)緩沖流
6.1.1 字節(jié)緩沖輸出流BfferedOutputStream
繼承自O(shè)utputStream,可使用父類共性方法(見2.1)
構(gòu)造方法:
- BufferedOutputStream(OutputStream out):創(chuàng)建一個(gè)新的緩沖輸出流,以數(shù)據(jù)寫入指定的底層輸出流。
- BufferedOutputStream(OutputSteam out, int size):創(chuàng)建一個(gè)新的緩沖輸出流,以將具有指定緩沖區(qū)大小的數(shù)據(jù)寫入指定的底層輸出流。
使用步驟
6.1.2 字節(jié)緩沖輸入流BfferedInputStream
繼承自InputStream,可使用父類共性方法(見2.2)
構(gòu)造方法
- BufferedInputStream(InputStream in):創(chuàng)建一個(gè)新的緩沖輸入流,保存參數(shù)輸入流in。
- BufferedInputStream(InputSteam in, int size):創(chuàng)建一個(gè)具有指定緩沖區(qū)大小的BufferedInputStream保存其參數(shù),即輸入流。
使用步驟
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);}文件復(fù)制4MB的ppt的效率比較:
基本流(一次讀一個(gè)字節(jié)):17757 ms
緩沖流(一次讀一個(gè)字節(jié)):121 ms
基本流 + 數(shù)組緩沖區(qū)(一次讀多個(gè)字節(jié)):27 ms
緩沖流 + 數(shù)組緩沖區(qū)(一次讀多個(gè)字節(jié)):9 ms
6.2 字符緩沖流
6.2.1 字符緩沖輸出流BufferedWriter
繼承自Writer,可使用父類共性方法(見3.2)
構(gòu)造方法
- BufferedWriter(Writer out):創(chuàng)建一個(gè)使用默認(rèn)大小輸出緩沖區(qū)的緩沖字符輸出流。
- BufferedWriter(Writer out, int size):創(chuàng)建一個(gè)使用指定大小輸出緩沖區(qū)的緩沖字符輸出流。
特有方法
- void newLine():寫入一個(gè)行分隔符,它會(huì)根據(jù)不同的操作系統(tǒng),獲取不同的行分隔符。
使用步驟
6.2.2 字符緩沖輸入流BufferedReader
繼承自Reader,可使用父類共性方法(見3.1)
構(gòu)造方法
- BufferedReader(Reader in):創(chuàng)建一個(gè)使用默認(rèn)大小輸入緩沖區(qū)的緩沖字符輸入流。
- BufferedReader(Reader in, int size):創(chuàng)建一個(gè)使用指定大小輸入緩沖區(qū)的緩沖字符輸入流。
特有方法
- String readLine():讀取一行文本,讀取一行數(shù)據(jù),流末尾返回null,readLine不讀換行符
使用步驟
6.3 緩沖流練習(xí)-文本排序
b.txt內(nèi)容:
7.77777777777777
3.張三3333333333
5.王五5555555555
1.大一1111111111
4.李四4444444444
2.小二2222222222
6.六六6666666666
7 轉(zhuǎn)換流
7.1 字符編碼和字符集
字符編碼
計(jì)算機(jī)中儲(chǔ)存的信息都是用二進(jìn)制數(shù)表示的,而我們?cè)谄聊簧峡吹降臄?shù)字、英文、標(biāo)點(diǎn)符號(hào)、漢字等字符是二進(jìn)制數(shù)轉(zhuǎn)換之后的結(jié)果。按照某種規(guī)則,將字符存儲(chǔ)到計(jì)算機(jī)中,稱為編碼 。反之,將存儲(chǔ)在計(jì)算機(jī)中的二進(jìn)制數(shù)按照某種規(guī)則解析顯示出來,稱為解碼 。比如說,按照A規(guī)則存儲(chǔ),同樣按照A規(guī)則解析,那么就能顯示正確的文本f符號(hào)。反之,按照A規(guī)則存儲(chǔ),再按照B規(guī)則解析,就會(huì)導(dǎo)致亂碼現(xiàn)象。
字符編碼Character Encoding : 就是一套自然語言的字符與二進(jìn)制數(shù)之間的對(duì)應(yīng)規(guī)則。
字符集
字符集 Charset :也叫編碼表。是一個(gè)系統(tǒng)支持的所有字符的集合,包括各國家文字、標(biāo)點(diǎn)符號(hào)、圖形符號(hào)、數(shù)字等。計(jì)算機(jī)要準(zhǔn)確的存儲(chǔ)和識(shí)別各種字符集符號(hào),需要進(jìn)行字符編碼,一套字符集必然至少有一套字符編碼。常見字符集有ASCII字符集、GBK字符集、Unicode字符集等。
ASCII是最基本的編碼表,GBK是中文編碼表
Unicode是萬國碼,兼容各種語言,是應(yīng)用中優(yōu)先采用的編碼。
7.2 編碼常見問題
例如:在IDEA中,使用FileReader 讀取項(xiàng)目中的文本文件。由于IDEA的設(shè)置,都是默認(rèn)的UTF-8編碼,所以沒有任何問題。但是,當(dāng)讀取Windows系統(tǒng)中創(chuàng)建的文本文件時(shí),由于Windows系統(tǒng)的默認(rèn)是GBK編碼,就會(huì)出現(xiàn)亂碼。
解決方法:使用轉(zhuǎn)換流
7.3 轉(zhuǎn)換流相關(guān)內(nèi)容
字節(jié)轉(zhuǎn)換為字符(解碼)
FileInputStream —> 查詢編碼表 —> FileReader
7.3.1 OutputStreamWriter
字符流通向字節(jié)流的橋梁
可以指定編碼格式
寫入你想寫入的編碼格式的文件中
構(gòu)造方法
- OutputStreamWriter(OutputStream out):創(chuàng)建使用默認(rèn)字符編碼的OutputStreamWriter(utf8)
- OutputStreamWriter(OutputStream out, String charSet):創(chuàng)建使用指定字符編碼的OutputStreamWriter
使用步驟
你好 GBK 4字節(jié) UTF8 6字節(jié)
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
字節(jié)流通向字符流的橋梁
可以指定編碼格式
讀取字節(jié)解碼為字符 把看不懂的變成看得懂的
構(gòu)造方法
- InputStreamReader(InputStream in):創(chuàng)建使用默認(rèn)字符編碼的OutputStreamWriter(utf8)
- InStreamReader(InputStream in, String charSet):創(chuàng)建使用指定字符編碼的InputStreamReader
使用步驟
注意:如果文件編碼和指定編碼不一致,則會(huì)發(fā)生亂碼
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 練習(xí):轉(zhuǎn)換文件編碼
將GBK編碼的文本文件,轉(zhuǎn)換為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對(duì)象的序列化流
把對(duì)象以流的方式寫入到文件中保存,叫寫對(duì)象,也叫對(duì)象的序列化。對(duì)象中包含的不僅是字符,使用字節(jié)流。
ObjectInputStream對(duì)象的反序列化流
把文件中的對(duì)象,以流的方式讀取出來,叫讀對(duì)象,也叫對(duì)象的反序列化。文件保存的都是字節(jié),使用字節(jié)流。
8.2 對(duì)象的序列化流ObjectOutputStream
構(gòu)造方法
- ObjectOutputStream(OutputStream out)
特有方法
- void writeObject(Object obj)
使用步驟
序列化和反序列化時(shí),會(huì)拋出NotSerializableException沒有序列化異常。
類通過實(shí)現(xiàn)Serializable接口以啟動(dòng)序列化功能,沒有實(shí)現(xiàn)此接口的類無法使其任何狀態(tài)序列化或反序列化。
Serializable接口也叫標(biāo)記型接口,進(jìn)行序列化和反序列化,必須要實(shí)現(xiàn)Serializable接口,給類添加標(biāo)記。在使用時(shí),會(huì)檢測是否有標(biāo)記。
使用前提
Person類的實(shí)現(xiàn) 要加上implement Serializable
8.3 對(duì)象的反序列化流ObjectInputStream
構(gòu)造方法
- ObjectInputStream(InputStream in)
特有方法
- void readObject(Object obj) 讀取對(duì)象
使用步驟
readObject方法聲明拋出了ClassFoundException,class文件找不到異常,當(dāng)不存在對(duì)象的class文件時(shí)拋出異常
使用前提
Person類的實(shí)現(xiàn) 要加上implement Serializable
對(duì)象的class類文件要存在
【注意!!!】
InvalidClassException異常:序列化之后對(duì)類進(jìn)行更改之后,不重新序列化,而是直接反序列化會(huì)出現(xiàn)異常。
因?yàn)閖avac編譯器會(huì)把java文件編譯生成class文件。類如果實(shí)現(xiàn)了Serializable接口,就會(huì)根據(jù)類的定義給類的class文件添加一個(gè)序列化號(hào)serialVersionUID,輸出的文件也會(huì)寫入這個(gè)ID,反序列化的時(shí)候,會(huì)使用class文件的序列號(hào)和輸出文件的序列號(hào)比較,如果ID一致,則反序列化一致,否則會(huì)拋出InvalidClassException異常。
而修改了類的定義之后,會(huì)給class文件重新編譯生成一個(gè)新的序列號(hào),但是輸出文件的序列號(hào)沒有改。
解決方案:手動(dòng)給類加一個(gè)序列號(hào)。無論是否修改類都不再修改序列號(hào)。
自定義類中添加成員常量。
private static final long serialVersionID = 1L;瞬態(tài)關(guān)鍵字transient
static靜態(tài)關(guān)鍵字:靜態(tài)優(yōu)先于非靜態(tài)加載到內(nèi)存中,(靜態(tài)優(yōu)先于對(duì)象),所以static修飾的成員變量是不能被序列化的,序列化的都是對(duì)象。
【在上例中,如果Person類的age成員變量是靜態(tài)的,序列化和非序列化age將永遠(yuǎn)是初始值0,無法更改】
transient瞬態(tài)關(guān)鍵字:被它修飾的成員變量不能被序列化。如果想要對(duì)象中的成員變量不被序列化,可以使用瞬態(tài)關(guān)鍵字。
8.4 練習(xí):序列化集合
當(dāng)我們想在文件中保存多個(gè)對(duì)象的時(shí)候,可以把對(duì)象存在集合中,對(duì)集合進(jìn)行序列化和反序列化。
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類
平時(shí)我們?cè)诳刂婆_(tái)打印輸出,是調(diào)用print方法和println方法完成的,這兩個(gè)方法都來自于java.io.PrintStream類,該類能夠方便地打印各種數(shù)據(jù)類型的值,是一種便捷的輸出方式。
特點(diǎn):
- 不會(huì)拋出IO異常
- 只負(fù)責(zé)輸出,不負(fù)責(zé)讀取
- 特有方法print、println
構(gòu)造方法:
- PrintStream(File file):輸出目的地是一個(gè)文件
- PrintStream(OutputStream out):輸出目的地是一個(gè)字節(jié)輸出流
- PrintStream(String path):輸出目的地是一個(gè)文件路徑
注意:
- 如果用繼承父類的write方法寫數(shù)據(jù),查看數(shù)據(jù)的時(shí)候就會(huì)查詢編碼表,再打印
- 如果使用特有方法print和println則會(huì)原樣輸出
可以改變輸出語句的目的地,即打印流的流向。
輸出語句,默認(rèn)在控制臺(tái)輸出,使用System.setOut方向改變輸出語句的目的地改為參數(shù)中傳遞的打印流的目的地。
總結(jié)
以上是生活随笔為你收集整理的【Java】关于Java中的各种流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RabbitMQ 简介和使用
- 下一篇: 【Java】函数式编程