day012 IO【轉換流、列印流、序列化】
1 字元流
1.1 字元編碼表
編碼表就是位元組(數字)和字元(漢字或者其他語言)的對應關係表。
ASCII: 1位元組(0 + 7個二進位制位) 128個字元
iso8859-1(latin) 1位元組 256個字元。
gb2312(1980) 1/2 個位元組 包含了六千多中文或者符號。
big5 1/2 個位元組 支援繁體字。
gbk 1/2 位元組 支援兩萬多的漢字以及字元。
unicode:國際標準碼錶。 可以表示任何國家的任何語言,並且任何字元都採用兩個位元組去儲存。 unicode8.0 甚至支援emoji。
UTF-8:萬國碼
UTF-32: 採用4個位元組去儲存。
UTF-16:採用2/3/4個位元組去儲存。
UTF-8: 採用1/2/3/4個位元組去儲存。
只需要知道兩個。
gbk: 中文在gbk中佔2個位元組。
utf-8: 中文在utf-8中佔3個
文字--->(數字) :編碼:就是看能看懂內容,轉換成看不懂的內容。
(數字)--->文字 : 解碼: 就是把看不懂的內容,轉換成看懂的內容。
1.2 io分類回顧
2 轉換流
2.1 轉換流寫入和讀取的工作流程
2.2 OutputStreamWriter
OutputStreamWriter 是轉換流。 是字元通向位元組的橋樑。
可以指定編碼集進行寫入。
構造方法:
OutputStreamWriter(OutputStream out): 需要傳遞一個位元組輸出流。 採用預設編碼方式進行寫入。
OutputStreamWriter(OutputStream out, String charsetName): 第一個引數為位元組輸出流,第二個引數為編碼集名稱。 可以指定編碼集進行寫入。
寫入方法。
寫入方法,和之前字元流的寫入方法是一樣的。因為OutputStreamWriter屬於字元流。
注意:
轉換流本身並不具備讀或者寫的功能,它的作用是查詢碼錶進行轉碼。
讀或者寫真正是由位元組流做的
指定的編碼集必須要存在,如果不存在就會報錯
ANSI 在windows指的就是gbk。
2.3 OutputStreamReader
InputStreamReader 也是轉換流。 位元組通向字元的橋樑。
這個流可以指定編碼進行讀取。
構造方法:
InputStreamReader(InputStream in):傳遞一個位元組輸入流。 以預設編碼方式進行讀取。
InputStreamReader(InputStream in, String charsetName): 第一個是位元組輸入流。第二個是指定的編碼方式。可以指定編碼進行讀取。
讀取的方法:
通過轉換流讀取。 以字元為單位。 因為轉換流屬於字元流的一種。
注意:程式碼中是以字元為單位讀的。但是內部會使用InputStream位元組輸入流,以位元組為單位讀取。
注意:
轉換流本身並不具備讀或者寫的功能。它的作用查詢碼錶進行轉碼。
資料其實真正是由位元組流讀或者寫的。
檔案是使用哪種編碼儲存,那麼讀取的時候就要指定哪種編碼,否則就會出現亂碼。
轉換流作用:
可以指定編碼集進行讀寫。
2.4 InputStreamReader
InputStreamReader 也是轉換流。 位元組通向字元的橋樑。
這個流可以指定編碼進行讀取。
構造方法
InputStreamReader(InputStream in):傳遞一個位元組輸入流。 以預設編碼方式進行讀取。
InputStreamReader(InputStream in, String charsetName): 第一個是位元組輸入流。第二個是指定的編碼方式。可以指定編碼進行讀取。
讀取的方法:
通過轉換流讀取。 以字元為單位。 因為轉換流屬於字元流的一種。
注意:程式碼中是以字元為單位讀的。但是內部會使用InputStream位元組輸入流,以位元組為單位讀取。
注意:
轉換流本身並不具備讀或者寫的功能。它的作用查詢碼錶進行轉碼。
資料其實真正是由位元組流讀或者寫的。
檔案是使用哪種編碼儲存,那麼讀取的時候就要指定哪種編碼,否則就會出現亂碼。
轉換流作用:
可以指定編碼集進行讀寫。
2.4 轉換流和子類的區別
字元流的繼承體系。
字元輸出流:
Writer: 是頂層父類。 是一個抽象類。
|-- OutputStreamWriter: 轉換流,可以指定編碼方式進行寫入。
|-- FileWriter: 是以預設的編碼方式進行寫入。 是父類的一個更簡單的用法。
字元輸入流:
Reader: 頂層父類,是一個抽象類。
|-- InputStreamReader:轉換流,可以指定編碼進行讀取。
|-- FileReader: 是以預設編碼進行讀取。 是父類更簡單的寫法。
總結:以下三種寫法是一樣的
使用轉換流指定一個編碼方式,這個指定的編碼方式為gbk。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file03.txt"), "gbk");
使用轉換流,不指定編碼方式,會採用的預設的gbk。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file03.txt"));
使用子類FileWriter,採用的就是預設的gbk。
FileWriter fw = new FileWriter("file03.txt");
3 序列化流
3.1 ObjectOutputStream 序列化流
ObjectOutputStream 叫做序列化流,可以將java程式中的物件寫入到檔案中。
構造方法:
ObjectOutputStream(OutputStream out): 傳遞一個位元組輸出流物件。
其他方法:
void writeObject(Object obj):向檔案中寫入一個物件。
要寫入的物件必須實現一個介面。這個介面叫做Serializable,如果沒有實現這個介面,就會引發NotSerializableException
寫入進去的內容我們是看不懂,因為它不是給我們看的。
3.2 ObjectInputStream 反序列化流
ObjectInputStream叫做反序列化流, 用來從檔案中讀取物件。
構造方法
ObjectInputStream(InputStream in): 傳遞一個位元組輸入流
讀取物件的方法:
Object readObject(): 讀取物件
注意:如果讀取物件的時候,這個物件的class檔案不存在,就會引發ClassNotFoundException。
如果想要寫入多個物件,可以把這些物件放入到一個集合中,然後把集合寫入到檔案,最終再讀取。
3.3 Serializable介面
Serializable 是序列化介面,一個類的物件想要被序列化,必須要實現這個介面。
這個介面中沒有任何方法,它的作用只是做一個標記,實現這個介面的類的物件才能夠被序列化。
3.4 注意
1. 被static修飾的成員,不會被序列化。
2. 如果希望某個物件的成員變數在序列化的時候不要寫入到檔案中,同時也不希望使用static。
可以使用另外一個關鍵字,這個關鍵字叫做transient。
transient 表示瞬態,被transient修飾的屬性不會被序列化。
3.5 版本號衝突問題及解決方法
如果向檔案中寫入一個物件後,對這個物件所在的類進行修改,然後再讀取就會引發異常。
原因是因為讀取前和讀取後的版本號(序列化)不一致
如何解決?
可以給這個類分配一個固定的版本號,這樣這個類無論怎麼修改,這個版本號都不會變。
如何給這個類分配一個固定的版本號?
直接在這個類中給出一個靜態常量,叫做serialVersionUID。 這個靜態常量表示的就是版本號(序列化)的意思
4 列印流
特點:
1. 只有輸出,沒有輸入(只能寫,不能讀)
2. 使用比較方便。
PrintWriter(字元列印流):
構造方法:
PrintWriter(File file)
PrintWriter(OutputStream out)
PrintWriter(String fileName)
PrintWriter(Writer out)
PrintStream(位元組列印流):
構造方法:
PrintStream(File file)
PrintStream(OutputStream out)
PrintStream(String fileName)
列印流裡面寫入的方法。
write: 如果寫入的是數字,會查詢ASCII碼最終寫入這個數字對應的字元。
print: 如果寫入的是數字,會原樣寫入到檔案中。寫入之後不會換行。
println:寫入之後會自動換行。
使用步驟:
1. 建立列印流物件
2. 呼叫方法,進行寫入。
3. 釋放資源
列印流的自動重新整理
字元輸出流寫資料的時候需要重新整理。
位元組流寫的時候不需要重新整理
自動重新整理的要求
1. 輸出目標必須是流;
PrintWriter(OutputStream out, boolean autoFlush)
PrintWriter(Writer out, boolean autoFlush)
2. 第二的構造引數指定為true;
3. 必須呼叫println、printf或format之一才會生效。
5 Commons-IO 等第三方工具的使用
什麼是第三方?
第一方: Oracle官方。
第二方: 程式設計師自己。
第三方: 除此之外全部都是第三方。
後期用的東西大多都是由第三方提供的工具。
這些工具都會以jar包的形式給你。
jar包就是一種壓縮包。裡面放的都是.class檔案。
現在我們學的這個工具叫做commons-io,他也是第三方工具,也是也jar包的形式提供的,它對應的jar包是 commons-io-2.6.jar
commons-io 是由Apache(阿帕奇)提供的一個第三方工具,作用是簡化了我們對IO流的操作。
Apache是 美國開源基金組織。
後期很多框架或者其他工具都是由apache維護或者提供的。
比如: tomcat。 active-mq。 struts2。 haddop,commons-io
如果要使用第三方工具,必須要進行導jar包。(重要)
步驟:
1. 在當前專案下新建資料夾,叫做lib
2. 把要匯入的jar包拷貝到這個lib資料夾下。
3. 點選jar包 -> 右鍵 -> build path -> add to build path
在commons-io中,有一個工具類,可以完成很多功能,這個類叫做FileUtils
裡面的方法
static void writeStringToFile(File file, String data):向檔案中寫入字串。
static String readFileToString(File file):讀取檔案,並返回字串。
static void copyFile(File srcFile, File destFile): 複製檔案。srcFile原始檔。destFile目標檔案
static void copyDirectoryToDirectory(File srcDir, File destDir): 複製資料夾。
@Deprecated //這個東西叫做註解,這個註解的作用表示這個東西已經過時了,被用這個註解的方法,使用時方法就會被劃上橫線。
5.1 關聯原始碼
按住Ctrl點方法,然後點Attach Source...,然後點External location,然後如果原始碼是以檔案形式提供的就選External File,如果原始碼是以資料夾形式提供的,就選External Folder。
5 NIO介紹
BIO:同步阻塞IO
NIO:同步非阻塞IO。netty,dubbo
在指定IO操作的時候,可以去做其他事情。
NIO是基於 緩衝區, 通道,選擇器。
AIO:非同步非阻塞IO
阻塞指的是執行緒阻塞,執行緒在阻塞的時候就不能幹其他事情了。
阻塞:看成去銀行排隊取錢,一直ATM前面排隊。
非阻塞:去櫃檯拿個號,然後等著取錢,等著的時候,可以幹別的。
相關文章
- 流------緩衝流、轉換流、序列化流、列印流
- 轉換流與列印流
- Java之IO轉換流Java
- IO流(02)--屬性集、緩衝流、轉換流
- [java IO流]之 序列化流和反序列化流(ObjectOutputStream/ObjectInputStream)JavaObject
- [java IO流]之 萬能輸出流列印流printWriterJava
- Java基礎(八)——IO流2_緩衝流、轉換流Java
- Java基礎之IO轉換流學習Java
- 【Java基礎知識】IO流--標準輸入輸出流、列印流PrintStreamJava
- 轉換流
- 列印流
- IO流
- IO 流
- Java —— 轉換流Java
- 菜鳥學習筆記:Java提升篇6(IO流2——資料型別處理流、列印流、隨機流)筆記Java資料型別隨機
- Java_轉換流和緩衝流Java
- java -IO流Java
- Java IO流Java
- IO 字元流字元
- java - IO流Java
- javaSE<IO流>Java
- Java IO流Java
- Java IO: 流Java
- JavaSE:IO流Java
- Java——IO流Java
- IO流之 檔案操作字元流字元
- Java之IO流基礎流物件Java物件
- Java IO7:管道流、物件流Java物件
- Python基礎之IO流和序列化講解Python
- [java IO流]之 IO概述Java
- Java的IO流Java
- JavaSE-IO流Java
- Java IO流操作Java
- 11.IO 流
- 11.IO流
- IO流 檔案字元流FileReader、FlieWriter字元
- JAVA_基礎IO流物件流(三)Java物件
- Java基礎(八)——IO流1_位元組流、字元流Java字元